/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.apache.fineract.cn.anubis.api.v1.TokenConstants;
import org.apache.fineract.cn.anubis.token.TenantRefreshTokenSerializer;
import org.apache.fineract.cn.anubis.token.TokenSerializationResult;
import org.apache.fineract.cn.api.context.AutoUserContext;
import org.apache.fineract.cn.api.util.FeignTargetWithCookieJar;
import org.apache.fineract.cn.api.util.InvalidTokenException;
import org.apache.fineract.cn.api.util.NotFoundException;
import org.apache.fineract.cn.identity.api.v1.client.IdentityManager;
import org.apache.fineract.cn.identity.api.v1.domain.Authentication;
import org.apache.fineract.cn.identity.api.v1.domain.Password;
import org.apache.fineract.cn.identity.api.v1.domain.Permission;
import org.apache.fineract.cn.identity.api.v1.domain.User;
import org.apache.fineract.cn.test.domain.TimeStampChecker;
import org.apache.fineract.cn.test.env.TestEnvironment;
import org.apache.fineract.cn.test.fixture.TenantDataStoreTestContext;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Myrle Krantz
 */
public class TestRefreshToken extends AbstractComponentTest {
  private static final int ACCESS_TOKEN_TIME_TO_LIVE = 5;
  private static final int REFRESH_TOKEN_TIME_TO_LIVE = 10;

  @BeforeClass
  public static void setup() throws Exception {
    //Shorten access time to 5 seconds for test purposes.;
    System.getProperties().setProperty("identity.token.access.ttl", String.valueOf(ACCESS_TOKEN_TIME_TO_LIVE));
    System.getProperties().setProperty("identity.token.refresh.ttl", String.valueOf(REFRESH_TOKEN_TIME_TO_LIVE));
  }

  @Test(expected = InvalidTokenException.class)
  public void adminLoginAccessTokenShouldTimeOut() throws InterruptedException {
    try (final AutoUserContext ignore = loginAdmin()) {
      Thread.sleep(TimeUnit.SECONDS.toMillis(ACCESS_TOKEN_TIME_TO_LIVE + 1));
      getTestSubject().getUser(ADMIN_IDENTIFIER);
    }
  }

  @Test(expected = InvalidTokenException.class)
  public void adminLoginRefreshTokenShouldTimeOut() throws InterruptedException {
    getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));

    Thread.sleep(TimeUnit.SECONDS.toMillis(REFRESH_TOKEN_TIME_TO_LIVE + 1));

    getTestSubject().refresh();
  }

  @Test
  public void afterAccessTokenExpiresRefreshTokenShouldAcquireNewAccessToken() throws InterruptedException {
    getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));

    Thread.sleep(TimeUnit.SECONDS.toMillis(ACCESS_TOKEN_TIME_TO_LIVE + 1));

    final Authentication refreshAccessTokenAuthentication =
            getTestSubject().refresh();

    try (final AutoUserContext ignored = new AutoUserContext(ADMIN_IDENTIFIER, refreshAccessTokenAuthentication.getAccessToken())) {
      getTestSubject().changeUserPassword(ADMIN_IDENTIFIER, new Password(TestEnvironment.encodePassword(ADMIN_PASSWORD)));
    }
  }

  @Test(expected = InvalidTokenException.class)
  public void refreshTokenShouldGrantAccessOnlyToOneTenant()
  {
    getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));

    try (final TenantDataStoreTestContext ignored = TenantDataStoreTestContext.forRandomTenantName(cassandraInitializer)) {
      try (final AutoUserContext ignored2
                   = tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
        getTestSubject().initialize(TestEnvironment.encodePassword(ADMIN_PASSWORD));
      }

      getTestSubject().refresh();
    }
  }

  @Test
  public void expirationDatesShouldBeCorrectIsoDateTimes() throws InterruptedException {
    final Authentication authentication =
            getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));

    final TimeStampChecker preRefreshAccessTokenTimeStampChecker = TimeStampChecker.inTheFuture(Duration.ofSeconds(ACCESS_TOKEN_TIME_TO_LIVE));
    final TimeStampChecker refreshTokenTimeStampChecker = TimeStampChecker.inTheFuture(Duration.ofSeconds(REFRESH_TOKEN_TIME_TO_LIVE));

    Assert.assertNotNull(authentication);

    preRefreshAccessTokenTimeStampChecker.assertCorrect(authentication.getAccessTokenExpiration());
    refreshTokenTimeStampChecker.assertCorrect(authentication.getRefreshTokenExpiration());

    TimeUnit.SECONDS.sleep(3);
    final TimeStampChecker postRefreshAccessTokenTimeStampChecker = TimeStampChecker.inTheFuture(Duration.ofSeconds(ACCESS_TOKEN_TIME_TO_LIVE));

    final Authentication refreshedAuthentication = getTestSubject().refresh();

    postRefreshAccessTokenTimeStampChecker.assertCorrect(refreshedAuthentication.getAccessTokenExpiration());
    refreshTokenTimeStampChecker.assertCorrect(refreshedAuthentication.getRefreshTokenExpiration());
  }

  @Test
  public void bothRefreshMethodsShouldProduceSamePermissions() throws InterruptedException {
    final Permission userPermission = buildUserPermission();
    final ApplicationSignatureTestData appPlusSig;
    try (final AutoUserContext ignored
                 = tenantApplicationSecurityEnvironment.createAutoSeshatContext()) {
      appPlusSig = setApplicationSignature();
      createApplicationPermission(appPlusSig.getApplicationIdentifier(), userPermission);
    }

    try (final AutoUserContext ignored = loginAdmin()) {
      getTestSubject().setApplicationPermissionEnabledForUser(
              appPlusSig.getApplicationIdentifier(),
              userPermission.getPermittableEndpointGroupIdentifier(),
              ADMIN_IDENTIFIER,
              true);
    }

    final TenantRefreshTokenSerializer refreshTokenSerializer = new TenantRefreshTokenSerializer();

    final TokenSerializationResult tokenSerializationResult =
            refreshTokenSerializer.build(new TenantRefreshTokenSerializer.Specification()
                    .setUser(ADMIN_IDENTIFIER)
                    .setSecondsToLive(30)
                    .setKeyTimestamp(appPlusSig.getKeyTimestamp())
                    .setPrivateKey(appPlusSig.getKeyPair().privateKey())
                    .setSourceApplication(appPlusSig.getApplicationIdentifier()));

    final FeignTargetWithCookieJar<IdentityManager> identityManagerWithCookieJar
            = apiFactory.createWithCookieJar(IdentityManager.class, testEnvironment.serverURI());

    identityManagerWithCookieJar.putCookie("/token", TokenConstants.REFRESH_TOKEN_COOKIE_NAME, tokenSerializationResult.getToken());

    final Authentication applicationAuthenticationViaCookie = identityManagerWithCookieJar.getFeignTarget().refresh();

    final Authentication applicationAuthenticationViaParam = getTestSubject().refresh(tokenSerializationResult.getToken());

    try (final AutoUserContext ignored = new AutoUserContext(ADMIN_IDENTIFIER, applicationAuthenticationViaCookie.getAccessToken()))
    {
      checkAccessToUsersAndOnlyUsers();
    }

    try (final AutoUserContext ignored = new AutoUserContext(ADMIN_IDENTIFIER, applicationAuthenticationViaParam.getAccessToken()))
    {
      checkAccessToUsersAndOnlyUsers();
    }

  }

  private void checkAccessToUsersAndOnlyUsers() {
    final List<User> users = getTestSubject().getUsers();
    Assert.assertFalse(users.isEmpty());

    try {
      getTestSubject().getRoles();
      Assert.fail("Shouldn't be able to get roles with token for application for which roles are not permitted.");
    }
    catch (final NotFoundException ignored2) { }
  }

}
