/*
 * 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.commons.lang.RandomStringUtils;
import org.apache.fineract.cn.api.context.AutoUserContext;
import org.apache.fineract.cn.api.util.NotFoundException;
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.UserWithPassword;
import org.apache.fineract.cn.identity.api.v1.events.EventConstants;
import org.apache.fineract.cn.test.domain.TimeStampChecker;
import org.apache.fineract.cn.test.env.TestEnvironment;
import org.junit.Assert;
import org.junit.Test;

import java.time.Duration;

/**
 * @author Myrle Krantz
 */
public class TestPasswords extends AbstractComponentTest {

  @Test
  public void testAdminChangeUserPassword() throws InterruptedException {
    final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, ADMIN_ROLE);

    try (final AutoUserContext ignore = loginAdmin()) {
      final String newPassword = TestEnvironment.encodePassword(
              AHMES_PASSWORD + "make_it_a_little_longer");

      {
        //Important here is that we are changing the password *as*the*admin*.
        getTestSubject().changeUserPassword(username, new Password(newPassword));
        boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, username);
        Assert.assertTrue(found);
      }

      final Authentication newPasswordAuthentication = getTestSubject().login(username, newPassword);
      try (final AutoUserContext ignore2 = new AutoUserContext(username, newPasswordAuthentication.getAccessToken()))
      {
        getTestSubject().createUser(new UserWithPassword("Ahmes_friend", "scribe",
                TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD)));
        Assert.fail("createUser should've thrown an exception because the password is admin reset.");
      }
      catch (final NotFoundException ex)
      {
        //Should throw because under the new password, the user has only the right to change the password.
      }

      try (final AutoUserContext ignore3 = new AutoUserContext(username, newPasswordAuthentication.getAccessToken()))
      {
        getTestSubject().changeUserPassword(username, new Password(newPassword));
        boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, username);
        Assert.assertTrue(found);
      }

      final Authentication newPasswordAuthenticationAsFullyPermissionedUser = getTestSubject().login(username, newPassword);
      try (final AutoUserContext ignore4 = new AutoUserContext(username, newPasswordAuthenticationAsFullyPermissionedUser.getAccessToken()))
      {
        //Now it should be possible to create a user since the user changed the password herself.
        getTestSubject().createUser(new UserWithPassword("Ahmes_friend", "scribe",
                TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD)));
      }
    }
  }

  @Test
  public void testAdminChangeAdminPassword() throws InterruptedException {
    try (final AutoUserContext ignore = loginAdmin()) {
      final String newPassword = TestEnvironment.encodePassword(
              ADMIN_PASSWORD + "make_it_a_little_longer");

      {
        getTestSubject().changeUserPassword(ADMIN_IDENTIFIER, new Password(newPassword));

        final boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, ADMIN_IDENTIFIER);
        Assert.assertTrue(found);
      }

      try {
        final String oldPassword = TestEnvironment.encodePassword(ADMIN_PASSWORD);
        getTestSubject().login(ADMIN_IDENTIFIER, oldPassword);
        Assert.fail("Login with the old password should not succeed.");
      } catch (final NotFoundException ignored) {
      }

      getTestSubject().login(ADMIN_IDENTIFIER, newPassword);

      {
        //Change the password back so the tests after this don't fail.
        getTestSubject().changeUserPassword(ADMIN_IDENTIFIER, new Password(TestEnvironment.encodePassword(ADMIN_PASSWORD)));
        boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, ADMIN_IDENTIFIER);
        Assert.assertTrue(found);
      }
    }
  }

  @Test
  public void testUserChangeOwnPasswordButNotAdminPassword() throws InterruptedException {
    final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, "scribe");

    try (final AutoUserContext ignored = loginUser(username, AHMES_PASSWORD))
    {
      final String newPassword = "new password";
      {
        getTestSubject().changeUserPassword(username, new Password(TestEnvironment.encodePassword(newPassword)));

        boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, username);
        Assert.assertTrue(found);
      }

      final TimeStampChecker passwordExpirationChecker = TimeStampChecker.inTheFutureWithWiggleRoom(Duration.ofDays(93), Duration.ofHours(24));
      final Authentication userAuthenticationAfterPasswordChange = getTestSubject().login(username, TestEnvironment.encodePassword(newPassword));
      final String passwordExpiration = userAuthenticationAfterPasswordChange.getPasswordExpiration();
      passwordExpirationChecker.assertCorrect(passwordExpiration);

      //noinspection EmptyCatchBlock
      try {
        getTestSubject().changeUserPassword(ADMIN_IDENTIFIER, new Password(TestEnvironment.encodePassword(newPassword)));
        Assert.fail("trying to change the admins password should fail.");
      }
      catch (final NotFoundException ex) {
        boolean found = eventRecorder.wait(EventConstants.OPERATION_PUT_USER_PASSWORD, ADMIN_IDENTIFIER);
        Assert.assertFalse(found);
      }


      try {
        getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(newPassword));
        Assert.fail("logging into admin with the new password should likewise fail.");
      }
      catch (final NotFoundException ex) {
        //Not found is expected.
      }

      //noinspection EmptyTryBlock
      try (final AutoUserContext ignored2 = loginAdmin()) { //logging into admin with the old password should *not* fail.
      }
    }
  }

  @Test(expected = IllegalArgumentException.class)
  public void loginWithUnencodedPasswordShouldThrowIllegalArgumentException() throws InterruptedException {

    try (final AutoUserContext ignored = loginAdmin()) {
      final String selfManagementRoleId = createSelfManagementRole();

      final String userPassword = RandomStringUtils.randomAlphanumeric(5);
      final String userid = createUserWithNonexpiredPassword(userPassword, selfManagementRoleId);

      getTestSubject().login(userid, userPassword);
    }

  }

  @Test
  public void activatedAntonyPasswordDoesntExpire() throws InterruptedException {

    try (final AutoUserContext ignored = loginAdmin()) {
      final Authentication adminAuthentication =
              getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));
      Assert.assertEquals(null, adminAuthentication.getPasswordExpiration());
    }
  }

  @Test
  public void onlyAntonyCanSetAntonyPassword() throws InterruptedException {
    try (final AutoUserContext ignored = loginAdmin()) {

      final String roleIdentifier = createRole(buildUserPermission(), buildSelfPermission(), buildRolePermission());
      final String username = createUserWithNonexpiredPassword(AHMES_PASSWORD, roleIdentifier);

      try (final AutoUserContext ignored2 = loginUser(username, AHMES_PASSWORD)) {
        getTestSubject().changeUserPassword(ADMIN_IDENTIFIER, new Password(TestEnvironment.encodePassword(AHMES_FRIENDS_PASSWORD)));
        Assert.fail("Should not be able to change antony's password from any account other than antony's.");
      }
      catch (final IllegalArgumentException expected) {
        //noinspection EmptyCatchBlock
      }
    }

    getTestSubject().login(ADMIN_IDENTIFIER, TestEnvironment.encodePassword(ADMIN_PASSWORD));
  }
}
