/*
 * 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.
 */
package org.apache.nifi.web.security.jwt.provider;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import org.apache.nifi.web.security.jwt.jws.JwsSignerContainer;
import org.apache.nifi.web.security.jwt.jws.JwsSignerProvider;
import org.apache.nifi.web.security.token.LoginAuthenticationToken;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.text.ParseException;
import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Date;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class StandardBearerTokenProviderTest {
    private static final String USERNAME = "USERNAME";

    private static final String IDENTITY = "IDENTITY";

    private static final Duration EXPIRATION = Duration.ofHours(1);

    private static final Duration MAXIMUM_DURATION_EXCEEDED = Duration.parse("PT12H5M");

    private static final Duration MINIMUM_DURATION_EXCEEDED = Duration.parse("PT30S");

    private static final String ISSUER = "ISSUER";

    private static final String KEY_ALGORITHM = "RSA";

    private static final int KEY_SIZE = 4096;

    private static final JWSAlgorithm JWS_ALGORITHM = JWSAlgorithm.PS512;

    @Mock
    private JwsSignerProvider jwsSignerProvider;

    private StandardBearerTokenProvider provider;

    private JWSVerifier jwsVerifier;

    private JWSSigner jwsSigner;

    @BeforeEach
    public void setProvider() throws NoSuchAlgorithmException {
        provider = new StandardBearerTokenProvider(jwsSignerProvider);

        final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGenerator.initialize(KEY_SIZE);
        final KeyPair keyPair = keyPairGenerator.generateKeyPair();
        jwsVerifier = new RSASSAVerifier((RSAPublicKey) keyPair.getPublic());
        jwsSigner = new RSASSASigner(keyPair.getPrivate());
    }

    @Test
    public void testGetBearerToken() throws ParseException, JOSEException {
        final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, EXPIRATION.toMillis(), ISSUER);
        setSignerProvider();

        final String bearerToken = provider.getBearerToken(loginAuthenticationToken);

        final SignedJWT signedJwt = assertTokenVerified(bearerToken);
        final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
        assertNotNull(claims.getIssueTime(), "Issue Time not found");
        assertNotNull(claims.getNotBeforeTime(), "Not Before Time not found");

        final Date claimExpirationTime = claims.getExpirationTime();
        assertNotNull(claimExpirationTime, "Expiration Time not found");

        final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
        assertEquals(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time not matched");

        assertEquals(ISSUER, claims.getIssuer());
        assertEquals(Collections.singletonList(ISSUER), claims.getAudience());
        assertEquals(IDENTITY, claims.getSubject());
        assertEquals(USERNAME, claims.getClaim(SupportedClaim.PREFERRED_USERNAME.getClaim()));
        assertNotNull("JSON Web Token Identifier not found", claims.getJWTID());
    }

    @Test
    public void testGetBearerTokenExpirationMaximum() throws ParseException, JOSEException {
        final long expiration = MAXIMUM_DURATION_EXCEEDED.toMillis();
        final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, expiration, ISSUER);
        setSignerProvider();

        final String bearerToken = provider.getBearerToken(loginAuthenticationToken);

        final SignedJWT signedJwt = assertTokenVerified(bearerToken);
        final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
        final Date claimExpirationTime = claims.getExpirationTime();
        assertNotNull(claimExpirationTime, "Expiration Time not found");

        final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
        assertNotSame(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time matched");

        assertTrue(claimExpirationTime.toInstant().isBefore(loginExpirationTime.toInstant()), "Claim Expiration after Login Expiration");
    }

    @Test
    public void testGetBearerTokenExpirationMinimum() throws ParseException, JOSEException {
        final long expiration = MINIMUM_DURATION_EXCEEDED.toMillis();
        final LoginAuthenticationToken loginAuthenticationToken = new LoginAuthenticationToken(IDENTITY, USERNAME, expiration, ISSUER);
        setSignerProvider();

        final String bearerToken = provider.getBearerToken(loginAuthenticationToken);

        final SignedJWT signedJwt = assertTokenVerified(bearerToken);
        final JWTClaimsSet claims = signedJwt.getJWTClaimsSet();
        final Date claimExpirationTime = claims.getExpirationTime();
        assertNotNull(claimExpirationTime, "Expiration Time not found");

        final Date loginExpirationTime = new Date(loginAuthenticationToken.getExpiration());
        assertNotSame(loginExpirationTime.toString(), claimExpirationTime.toString(), "Expiration Time matched");

        assertTrue(claimExpirationTime.toInstant().isAfter(loginExpirationTime.toInstant()), "Claim Expiration before Login Expiration");
    }

    private void setSignerProvider() {
        final String keyIdentifier = UUID.randomUUID().toString();
        final JwsSignerContainer jwsSignerContainer = new JwsSignerContainer(keyIdentifier, JWS_ALGORITHM, jwsSigner);
        when(jwsSignerProvider.getJwsSignerContainer(isA(Instant.class))).thenReturn(jwsSignerContainer);
    }

    private SignedJWT assertTokenVerified(final String bearerToken) throws ParseException, JOSEException {
        final SignedJWT signedJwt = SignedJWT.parse(bearerToken);
        assertTrue(signedJwt.verify(jwsVerifier), "Verification Failed");
        return signedJwt;
    }
}
