

package gov.va.med.cds.util;


import gov.va.med.cds.junit.runners.Suite;
import gov.va.med.cds.junit.runners.SuiteAwareRunner;
import gov.va.med.cds.properties.PropertiesUtil;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import javax.crypto.spec.SecretKeySpec;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith( SuiteAwareRunner.class )
public class PropertiesUtilTest
{

    public static final String PROPERTIES_FILE_PATH_PROPERTY = "cds.run.properties.path";
    public static final String PROPERTIES_ENCRYPTION_SWITCH = "cds.encrypt.password.properties";
    public static final String PROPERTIES_KEYSTORE_PASSWORD = "cds.keystore.password";
    public static final String PROPERTIES_TEST_PASSWORD ="cds.test.jdbc.password";
    private static String currentPropertiesFilePath;
    
    private static final String TEST_PLAIN_TEXT_PROPERTIES = "./src/test/resources/propertiesUtil/plainText.properties";
    // test creates <encrypted.properties> file, do not check it in
    private static final String TEST_ENCRYPTED_PROPERTIES = "./src/test/resources/propertiesUtil/encrypted.properties";
    


    @BeforeClass
     static public void beforePropertiesUtilTestClassSetUp() {
        currentPropertiesFilePath = System.getProperty( PROPERTIES_FILE_PATH_PROPERTY );
    }
    
    @AfterClass
     static public void afterPropertiesUtilTestClassSetUp() {
        //this will set it back to original setting ...
        if ( currentPropertiesFilePath != null )
        {
            System.setProperty( PROPERTIES_FILE_PATH_PROPERTY, currentPropertiesFilePath );
        }
        //turn off encryption
        System.setProperty( PROPERTIES_ENCRYPTION_SWITCH, "false" );
    }

    
    
    @Test 
    @Suite( groups = "slowtest", order = 1 )
    public void testLoadSystemRunPropertiesWithEncryption( )
        throws Exception
    {
            System.setProperty( PROPERTIES_FILE_PATH_PROPERTY, TEST_PLAIN_TEXT_PROPERTIES );
            System.setProperty( PROPERTIES_ENCRYPTION_SWITCH, "true" );
            System.setProperty( PROPERTIES_KEYSTORE_PASSWORD, "shutup" );
            PropertiesUtil pu = new PropertiesUtil() { 
                @Override
                protected void encryptProperties( String propertiesFilePath, Properties fileProps, SecretKeySpec savedKey )
                    throws IOException
                {
                    super.encryptProperties( TEST_ENCRYPTED_PROPERTIES, fileProps, savedKey );
                }
            };
            pu.loadSystemRunProperties();
            String systemPassword = System.getProperty( PROPERTIES_TEST_PASSWORD );
            Assert.assertEquals( "testPass", systemPassword );
            
            // check that password has been encrypted
            Properties puAfterEncription = new Properties();
            puAfterEncription.load(new FileInputStream( TEST_ENCRYPTED_PROPERTIES ));
            Assert.assertTrue(puAfterEncription.getProperty(PROPERTIES_TEST_PASSWORD).startsWith( "{AES}" ));
    }

    @Test 
    @Suite( groups = "slowtest", order = 2 )
    public void testLoadSystemRunPropertiesAndDecrypt( )
        throws Exception
    {
            System.setProperty( PROPERTIES_FILE_PATH_PROPERTY, TEST_ENCRYPTED_PROPERTIES );
            System.setProperty( PROPERTIES_ENCRYPTION_SWITCH, "false" );
            System.setProperty( PROPERTIES_KEYSTORE_PASSWORD, "shutup" );

            new PropertiesUtil().loadSystemRunProperties();
            String decryptedPassword = System.getProperty( PROPERTIES_TEST_PASSWORD );
            Assert.assertEquals( "testPass", decryptedPassword );
            
            // check that password remains encrypted
            Properties puAfterEncription = new Properties();
            puAfterEncription.load(new FileInputStream( TEST_ENCRYPTED_PROPERTIES ));
            Assert.assertTrue(puAfterEncription.getProperty(PROPERTIES_TEST_PASSWORD).startsWith( "{AES}" ));
            
    }

    @Test 
    @Suite( groups = "slowtest", order = 3 )
    public void testLoadSystemRunPropertiesWithoutEncryption( )
        throws Exception
    {
            System.setProperty( PROPERTIES_ENCRYPTION_SWITCH, "false" );
            System.setProperty( PROPERTIES_FILE_PATH_PROPERTY, TEST_PLAIN_TEXT_PROPERTIES );
            new PropertiesUtil().loadSystemRunProperties();
            
            String decryptedPassword = System.getProperty( PROPERTIES_TEST_PASSWORD );
            Assert.assertEquals( "testPass", decryptedPassword );
            
            // check that password is plain text in .properties file
            Properties puAfterEncription = new Properties();
            puAfterEncription.load(new FileInputStream( TEST_PLAIN_TEXT_PROPERTIES ));
            Assert.assertEquals("testPass", puAfterEncription.getProperty(PROPERTIES_TEST_PASSWORD));
          
    }

}
