/*
 * Copyright 2017 The Mifos Initiative.
 *
 * Licensed 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.
 */
package io.mifos.anubis.test.v1;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.jsonwebtoken.*;
import io.mifos.anubis.annotation.AcceptedTokenType;
import io.mifos.anubis.api.v1.RoleConstants;
import io.mifos.anubis.api.v1.TokenConstants;
import io.mifos.anubis.api.v1.domain.AllowedOperation;
import io.mifos.anubis.api.v1.domain.TokenContent;
import io.mifos.anubis.api.v1.domain.TokenPermission;
import io.mifos.anubis.provider.InvalidKeyTimestampException;
import io.mifos.anubis.provider.SystemRsaKeyProvider;
import io.mifos.anubis.security.SystemAuthenticator;
import io.mifos.anubis.service.PermittableService;
import io.mifos.anubis.token.SystemAccessTokenSerializer;
import io.mifos.anubis.token.TenantAccessTokenSerializer;
import io.mifos.core.api.context.AutoSeshat;
import io.mifos.core.api.context.AutoUserContext;
import io.mifos.core.api.util.ApiConstants;
import io.mifos.core.api.util.UserContextHolder;
import io.mifos.core.lang.ApplicationName;
import io.mifos.core.lang.TenantContextHolder;
import io.mifos.core.lang.security.RsaKeyPairFactory;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author Myrle Krantz
 */
@SuppressWarnings({"WeakerAccess", "unused"})
public class SystemSecurityEnvironment {
  final static String LOGGER_NAME = "anubis-test-logger";

  private final TenantAccessTokenSerializer tenantAccessTokenSerializer;
  private final SystemAccessTokenSerializer systemAccessTokenSerializer;
  private final String systemKeyTimestamp;
  private final PublicKey systemPublicKey;
  private final PrivateKey systemPrivateKey;
  private final Map<String, RsaKeyPairFactory.KeyPairHolder> tenantKeyPairHolders;

  public SystemSecurityEnvironment(final String systemKeyTimestamp, final PublicKey systemPublicKey, final PrivateKey systemPrivateKey) {
    final Gson gson = new GsonBuilder().create();
    this.tenantAccessTokenSerializer = new TenantAccessTokenSerializer(gson);
    this.systemAccessTokenSerializer = new SystemAccessTokenSerializer();
    this.systemKeyTimestamp = systemKeyTimestamp;
    this.systemPublicKey = systemPublicKey;
    this.systemPrivateKey = systemPrivateKey;

    this.tenantKeyPairHolders = new HashMap<>();
  }

  public AutoUserContext createAutoSystemContext(final String applicationName)
  {
    return new AutoSeshat(systemToken(applicationName));
  }

  public AutoUserContext createAutoSystemContext(final String tenantName, final String applicationName) {
    return new AutoSeshat(systemToken(tenantName, applicationName));
  }

  public String systemToken(final String applicationName) {
    return systemToken(TenantContextHolder.checkedGetIdentifier(), applicationName);
  }

  private String systemToken(final String tenantName, final String applicationName) {
    return systemAccessTokenSerializer.build(new SystemAccessTokenSerializer.Specification()
            .setTenant(tenantName)
            .setRole(RoleConstants.SYSTEM_ADMIN_ROLE_IDENTIFIER)
            .setSecondsToLive(TimeUnit.HOURS.toSeconds(12))
            .setKeyTimestamp(systemKeyTimestamp)
            .setPrivateKey(systemPrivateKey)
            .setTargetApplicationName(applicationName)
    ).getToken();
  }

  public AutoUserContext createAutoUserContext(final String userName, final List<String> applicationNames)
  {
    return new AutoUserContext(userName, getEverythingToken(userName, applicationNames));
  }

  private String getEverythingToken(final String userName, final List<String> applicationNames)
  {
    return tenantAccessTokenSerializer.build(new TenantAccessTokenSerializer.Specification()
            .setUser(userName)
            .setTokenContent(getTokenContentForStarEndpoint(applicationNames))
            .setSecondsToLive(TimeUnit.HOURS.toSeconds(10))
            .setKeyTimestamp(tenantKeyTimestamp())
            .setPrivateKey(tenantPrivateKey())).getToken();
  }

  public String getPermissionToken(
          final String userName,
          final String applicationName,
          final String uri,
          final AllowedOperation allowedOperation) {
    return tenantAccessTokenSerializer.build(
            new TenantAccessTokenSerializer.Specification().setPrivateKey(tenantPrivateKey())
                    .setKeyTimestamp(tenantKeyTimestamp())
                    .setSecondsToLive(100)
                    .setUser(userName)
                    .setTokenContent(generateOnePermissionTokenContent(applicationName, uri, allowedOperation))
    ).getToken();
  }

  private TokenContent generateOnePermissionTokenContent(final String applicationName, final String uri, final AllowedOperation allowedOperation) {
    final TokenPermission tokenPermission
            = new TokenPermission(applicationName + uri, Collections.singleton(allowedOperation));

    return new TokenContent(Collections.singletonList(tokenPermission));
  }

  public String tenantKeyTimestamp() {
    return tenantKeyPairHolders.computeIfAbsent(TenantContextHolder.checkedGetIdentifier(),
            x -> RsaKeyPairFactory.createKeyPair()).getTimestamp();
  }

  public RSAPublicKey tenantPublicKey()
  {
    return tenantKeyPairHolders.computeIfAbsent(TenantContextHolder.checkedGetIdentifier(),
            x -> RsaKeyPairFactory.createKeyPair()).publicKey();
  }

  public RSAPrivateKey tenantPrivateKey()
  {
    return tenantKeyPairHolders.computeIfAbsent(TenantContextHolder.checkedGetIdentifier(),
            x -> RsaKeyPairFactory.createKeyPair()).privateKey();
  }

  private TokenContent getTokenContentForStarEndpoint(final List<String> applicationNames) {
    return new TokenContent(
            applicationNames.stream()
            .map(x -> new TokenPermission(x + "/*", AllowedOperation.ALL))
            .collect(Collectors.toList()));
  }

  public boolean isValidGuestSecurityContext(final String forTenant) {
    final boolean validTenant = TenantContextHolder.identifier().map(x -> x.equals(forTenant)).orElse(false);
    final boolean validUser = UserContextHolder.checkedGetUser().equals(RoleConstants.GUEST_USER_IDENTIFIER);
    final boolean validToken = UserContextHolder.checkedGetAccessToken().equals(TokenConstants.NO_AUTHENTICATION);

    return validTenant && validUser && validToken;
  }


  public boolean isValidSystemSecurityContext(final String forService, final String forServiceVersion, final String forTenant) {
    final boolean validTenant = TenantContextHolder.identifier().map(x -> x.equals(forTenant)).orElse(false);
    final boolean validUser = UserContextHolder.checkedGetUser().equals(ApiConstants.SYSTEM_SU);
    final boolean validToken = isValidToken(
            UserContextHolder.checkedGetAccessToken(),
            forService,
            forServiceVersion,
            UserContextHolder.checkedGetUser());

    return validTenant && validUser && validToken;
  }

  public boolean isValidToken(final String token,
                              final String forService,
                              final String forServiceVersion,
                              final String forUser) {
    if (!token.startsWith(TokenConstants.PREFIX))
      return false;

    final String jwtToken = token.substring(TokenConstants.PREFIX.length()).trim();

    final PermittableService permittableService = Mockito.mock(PermittableService.class);
    Mockito.doReturn(Collections.emptySet()).when(permittableService).getPermittableEndpointsAsPermissions(AcceptedTokenType.SYSTEM);

    final SystemRsaKeyProvider systemRsaKeyProvider = Mockito.mock(SystemRsaKeyProvider.class);
    try {
      Mockito.doReturn(systemPublicKey).when(systemRsaKeyProvider).getPublicKey(Mockito.anyString());
    }
    catch (final InvalidKeyTimestampException ignored) {}

    final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);

    final SystemAuthenticator systemAuthenticator = new SystemAuthenticator(
            systemRsaKeyProvider,
            ApplicationName.appNameWithVersion(forService, forServiceVersion),
            permittableService,
            logger);
    try {
      return (systemAuthenticator.authenticate(forUser, jwtToken, systemKeyTimestamp) != null);
    }
    catch (final Exception e)
    {
      return false;
    }
  }

  public static TokenContent getTokenContent(final String token, final PublicKey publicKey)
  {
    final String strippedAccessToken = token.substring("Bearer ".length());

    final JwtParser parser = Jwts.parser().setSigningKey(publicKey);

    @SuppressWarnings("unchecked") final Jwt<Header, Claims> jwt = parser.parse(strippedAccessToken);

    final String serializedTokenContent = jwt.getBody().get(TokenConstants.JWT_CONTENT_CLAIM, String.class);
    return new Gson().fromJson(serializedTokenContent, TokenContent.class);
  }
}
