/*
 * 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.registry.properties

import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import javax.crypto.Cipher
import java.security.Security

@RunWith(JUnit4.class)
class NiFiRegistryPropertiesLoaderGroovyTest extends GroovyTestCase {

    private static final Logger logger = LoggerFactory.getLogger(NiFiRegistryPropertiesLoaderGroovyTest.class)

    private static final String KEYSTORE_PASSWORD_KEY = NiFiRegistryProperties.SECURITY_KEYSTORE_PASSWD
    private static final String KEY_PASSWORD_KEY = NiFiRegistryProperties.SECURITY_KEY_PASSWD
    private static final String TRUSTSTORE_PASSWORD_KEY = NiFiRegistryProperties.SECURITY_TRUSTSTORE_PASSWD

    private static final String KEY_HEX_128 = "0123456789ABCDEFFEDCBA9876543210"
    private static final String KEY_HEX_256 = KEY_HEX_128 * 2
    private static final String KEY_HEX = Cipher.getMaxAllowedKeyLength("AES") < 256 ? KEY_HEX_128 : KEY_HEX_256

    private static final String PASSWORD_KEY_HEX_128 = "2C576A9585DB862F5ECBEE5B4FFFCCA1"

    @BeforeClass
    public static void setUpOnce() throws Exception {
        Security.addProvider(new BouncyCastleProvider())

        logger.metaClass.methodMissing = { String name, args ->
            logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
        }
    }

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
        // Clear the sensitive property providers between runs
        NiFiRegistryPropertiesLoader.@sensitivePropertyProviderFactory = null
    }

    @AfterClass
    public static void tearDownOnce() {
    }

    @Test
    public void testConstructorShouldCreateNewInstance() throws Exception {
        // Arrange

        // Act
        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Assert
        assert !propertiesLoader.@keyHex
    }

    @Test
    public void testShouldCreateInstanceWithKey() throws Exception {
        // Arrange

        // Act
        NiFiRegistryPropertiesLoader propertiesLoader = NiFiRegistryPropertiesLoader.withKey(KEY_HEX)

        // Assert
        assert propertiesLoader.@keyHex == KEY_HEX
    }

    @Test
    public void testConstructorShouldCreateMultipleInstances() throws Exception {
        // Arrange
        NiFiRegistryPropertiesLoader propertiesLoader1 = NiFiRegistryPropertiesLoader.withKey(KEY_HEX)

        // Act
        NiFiRegistryPropertiesLoader propertiesLoader2 = new NiFiRegistryPropertiesLoader()

        // Assert
        assert propertiesLoader1.@keyHex == KEY_HEX
        assert !propertiesLoader2.@keyHex
    }

    @Test
    public void testShouldGetDefaultProviderKey() throws Exception {
        // Arrange
        final String expectedProviderKey = "aes/gcm/${Cipher.getMaxAllowedKeyLength("AES") > 128 ? 256 : 128}"
        logger.info("Expected provider key: ${expectedProviderKey}")

        // Act
        String defaultKey = NiFiRegistryPropertiesLoader.getDefaultProviderKey()
        logger.info("Default key: ${defaultKey}")
        // Assert
        assert defaultKey == expectedProviderKey
    }

    @Test
    public void testShouldInitializeSensitivePropertyProviderFactory() throws Exception {
        // Arrange
        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Act
        propertiesLoader.initializeSensitivePropertyProviderFactory()

        // Assert
        assert propertiesLoader.@sensitivePropertyProviderFactory
    }

    @Test
    public void testShouldLoadUnprotectedPropertiesFromFile() throws Exception {
        // Arrange
        File unprotectedFile = new File("src/test/resources/conf/nifi-registry.properties")
        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Act
        NiFiRegistryProperties properties = propertiesLoader.load(unprotectedFile)

        // Assert
        assert properties.size() > 0

        // Ensure it is not a ProtectedNiFiProperties
        assert properties instanceof NiFiRegistryProperties
    }

    @Test
    public void testShouldNotLoadUnprotectedPropertiesFromNullFile() throws Exception {
        // Arrange
        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Act
        def msg = shouldFail(IllegalArgumentException) {
            NiFiRegistryProperties properties = propertiesLoader.load(null as File)
        }
        logger.info(msg)

        // Assert
        assert msg == "NiFi Registry properties file missing or unreadable"
    }

    @Test
    public void testShouldNotLoadUnprotectedPropertiesFromMissingFile() throws Exception {
        // Arrange
        File missingFile = new File("src/test/resources/conf/nifi-registry.missing.properties")
        assert !missingFile.exists()

        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Act
        def msg = shouldFail(IllegalArgumentException) {
            NiFiRegistryProperties properties = propertiesLoader.load(missingFile)
        }
        logger.info(msg)

        // Assert
        assert msg == "NiFi Registry properties file missing or unreadable"
    }

    @Test
    public void testShouldLoadUnprotectedPropertiesFromPath() throws Exception {
        // Arrange
        File unprotectedFile = new File("src/test/resources/conf/nifi-registry.properties")
        NiFiRegistryPropertiesLoader propertiesLoader = new NiFiRegistryPropertiesLoader()

        // Act
        NiFiRegistryProperties properties = propertiesLoader.load(unprotectedFile.path)

        // Assert
        assert properties.size() > 0

        // Ensure it is not a ProtectedNiFiProperties
        assert properties instanceof NiFiRegistryProperties
    }

    @Test
    public void testShouldLoadUnprotectedPropertiesFromProtectedFile() throws Exception {
        // Arrange
        File protectedFile = new File("src/test/resources/conf/nifi-registry.with_sensitive_props_protected_aes_128.properties")
        NiFiRegistryPropertiesLoader propertiesLoader = NiFiRegistryPropertiesLoader.withKey(KEY_HEX_128)

        final def EXPECTED_PLAIN_VALUES = [
                (KEYSTORE_PASSWORD_KEY): "thisIsABadPassword",
                (KEY_PASSWORD_KEY): "thisIsABadPassword",
        ]

        // This method is covered in tests above, so safe to use here to retrieve protected properties
        ProtectedNiFiRegistryProperties protectedNiFiProperties = propertiesLoader.readProtectedPropertiesFromDisk(protectedFile)
        int totalKeysCount = protectedNiFiProperties.getPropertyKeysIncludingProtectionSchemes().size()
        int protectedKeysCount = protectedNiFiProperties.getProtectedPropertyKeys().size()
        logger.info("Read ${totalKeysCount} total properties (${protectedKeysCount} protected) from ${protectedFile.canonicalPath}")

        // Act
        NiFiRegistryProperties properties = propertiesLoader.load(protectedFile)

        // Assert
        assert properties.size() == totalKeysCount - protectedKeysCount

        // Ensure that any key marked as protected above is different in this instance
        protectedNiFiProperties.getProtectedPropertyKeys().keySet().each { String key ->
            String plainValue = properties.getProperty(key)
            String protectedValue = protectedNiFiProperties.getProperty(key)

            logger.info("Checking that [${protectedValue}] -> [${plainValue}] == [${EXPECTED_PLAIN_VALUES[key]}]")

            assert plainValue == EXPECTED_PLAIN_VALUES[key]
            assert plainValue != protectedValue
            assert plainValue.length() <= protectedValue.length()
        }

        // Ensure it is not a ProtectedNiFiProperties
        assert properties instanceof NiFiRegistryProperties
    }

    @Test
    public void testShouldUpdateKeyInFactory() throws Exception {
        // Arrange
        File originalKeyFile = new File("src/test/resources/conf/nifi-registry.with_sensitive_props_protected_aes_128.properties")
        File passwordKeyFile = new File("src/test/resources/conf/nifi-registry.with_sensitive_props_protected_aes_128_password.properties")
        NiFiRegistryPropertiesLoader propertiesLoader = NiFiRegistryPropertiesLoader.withKey(KEY_HEX_128)

        NiFiRegistryProperties properties = propertiesLoader.load(originalKeyFile)
        logger.info("Read ${properties.size()} total properties from ${originalKeyFile.canonicalPath}")

        // Act
        NiFiRegistryPropertiesLoader passwordNiFiRegistryPropertiesLoader = NiFiRegistryPropertiesLoader.withKey(PASSWORD_KEY_HEX_128)

        NiFiRegistryProperties passwordProperties = passwordNiFiRegistryPropertiesLoader.load(passwordKeyFile)
        logger.info("Read ${passwordProperties.size()} total properties from ${passwordKeyFile.canonicalPath}")

        // Assert
        assert properties.size() == passwordProperties.size()


        def readPropertiesAndValues = properties.getPropertyKeys().collectEntries {
            [(it): properties.getProperty(it)]
        }
        def readPasswordPropertiesAndValues = passwordProperties.getPropertyKeys().collectEntries {
            [(it): passwordProperties.getProperty(it)]
        }

        assert readPropertiesAndValues == readPasswordPropertiesAndValues
    }
}
