

package gov.va.med.cds.properties;


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

import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.crypto.spec.SecretKeySpec;

import junit.framework.Assert;

import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith( SuiteAwareRunner.class )
public class PropertiesManagerTest
{

    private boolean calledConfigureKeyStore;
    private boolean calledDecrypt;


    @SuppressWarnings( { "rawtypes", "unchecked" } )
    @Test
    @Suite( groups = "checkintest" )
    public void testDecrypt_WhenKeyExist( )
        throws IOException
    {
        String keyStoreFileLocation = "path";
        String keyStorePassword = "storePassword";

        SecretKeySpec savedKeyMock = EasyMock.createMock( SecretKeySpec.class );
        Properties filePropsMock = EasyMock.createMock( Properties.class );

        PropertiesManager pm = new PropertiesManager()
        {
            @Override
            protected SecretKeySpec configureKeyStore( String keyStoreFileLocation, String keyStorePassword )
                throws IOException
            {
                calledConfigureKeyStore = true;
                return null;
            }


            @Override
            protected String decrypt( SecretKeySpec savedKey, String propValue )
            {
                calledDecrypt = true;
                return "plainTextPassd";
            }
        };

        Enumeration st = new StringTokenizer( "prop.password" );
        EasyMock.expect( filePropsMock.propertyNames() ).andReturn( st );
        EasyMock.expect( filePropsMock.getProperty( "prop.password" ) ).andReturn( "{AES}aN12344" );
        EasyMock.expect( filePropsMock.setProperty( "prop.password", "plainTextPassd" ) ).andReturn( null );
        EasyMock.replay( savedKeyMock, filePropsMock );

        pm.decryptProperties( savedKeyMock, keyStoreFileLocation, keyStorePassword, filePropsMock );
        Assert.assertFalse( calledConfigureKeyStore );
        Assert.assertTrue( calledDecrypt );

    }


    @SuppressWarnings( { "rawtypes", "unchecked" } )
    @Test
    @Suite( groups = "checkintest" )
    public void testDecrypt_WhenNoKey( )
        throws IOException
    {
        String keyStoreFileLocation = "path";
        String keyStorePassword = "storePassword";

        SecretKeySpec savedKeyMock = null;
        Properties filePropsMock = EasyMock.createMock( Properties.class );

        PropertiesManager pm = new PropertiesManager()
        {
            @Override
            protected SecretKeySpec configureKeyStore( String keyStoreFileLocation, String keyStorePassword )
                throws IOException
            {
                calledConfigureKeyStore = true;
                return null;
            }


            @Override
            protected String decrypt( SecretKeySpec savedKey, String propValue )
            {
                calledDecrypt = true;
                return "plainTextPassd";
            }
        };

        Enumeration st = new StringTokenizer( "prop.password" );
        EasyMock.expect( filePropsMock.propertyNames() ).andReturn( st );
        EasyMock.expect( filePropsMock.getProperty( "prop.password" ) ).andReturn( "{AES}aN12344" );
        EasyMock.expect( filePropsMock.setProperty( "prop.password", "plainTextPassd" ) ).andReturn( null );
        EasyMock.replay( filePropsMock );

        pm.decryptProperties( savedKeyMock, keyStoreFileLocation, keyStorePassword, filePropsMock );
        Assert.assertTrue( calledConfigureKeyStore );
        Assert.assertTrue( calledDecrypt );

    }


    @Test
    @Suite( groups = "checkintest" )
    public void testEncryptPropertiesFirstTime_EncryptPasswords( )
        throws Exception
    {
        String propertiesFile = "/home/hdrdev/projects/repositories/apps/cds/main/resources/properties/cds.properties";
        String encryptSwich = "true";
        String keyStoreFileLocation = "path.KeyStore";
        String keyStorePassword = "password";

        PropertiesManager propertiesManagerMock = EasyMock.createMock( PropertiesManager.class );
        Properties filePropertiesMock = EasyMock.createMock( Properties.class );
        SecretKeySpec secretKeySpecMock = EasyMock.createMock( SecretKeySpec.class );
        PropertiesUtil pu = new PropertiesUtil();
        pu.setPropertiesManager( propertiesManagerMock );

        EasyMock.expect( propertiesManagerMock.getPropertiesFilePathFromSystemProperties() ).andReturn( propertiesFile );
        EasyMock.expect( propertiesManagerMock.getEncryptSwitchFromSystemProperties() ).andReturn( encryptSwich );
        EasyMock.expect( propertiesManagerMock.getKeyStorePasswordFromSystemProperties() ).andReturn( keyStorePassword );
        EasyMock.expect( propertiesManagerMock.loadPropertiesFromPropertiesFile( propertiesFile ) ).andReturn( filePropertiesMock );
        EasyMock.expect( filePropertiesMock.getProperty( "cds.keystore.properties.path" ) ).andReturn( keyStoreFileLocation );
        EasyMock.expect( propertiesManagerMock.configureKeyStore( keyStoreFileLocation, keyStorePassword ) ).andReturn( secretKeySpecMock );
        Properties propertiesClone = new Properties();
        EasyMock.expect( filePropertiesMock.clone() ).andReturn( propertiesClone );
        propertiesManagerMock.encryptProperties( secretKeySpecMock, propertiesFile, propertiesClone );
        EasyMock.expect( propertiesManagerMock.decryptProperties( secretKeySpecMock, keyStoreFileLocation, keyStorePassword, filePropertiesMock ) )
                        .andReturn( filePropertiesMock );
        propertiesManagerMock.updateSystemProperties( filePropertiesMock );
        EasyMock.replay( propertiesManagerMock, filePropertiesMock, secretKeySpecMock );

        pu.loadSystemRunProperties();
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testLoadPlaneTextProperties_NoEncryption( )
        throws Exception
    {

        String propertiesFile = "/home/hdrdev/projects/repositories/apps/cds/main/resources/properties/cds.properties";
        String encryptSwich = null;
        String keyStoreFileLocation = null;
        String keyStorePassword = null;

        PropertiesManager propertiesManagerMock = EasyMock.createMock( PropertiesManager.class );
        Properties filePropertiesMock = EasyMock.createMock( Properties.class );
        PropertiesUtil pu = new PropertiesUtil();
        pu.setPropertiesManager( propertiesManagerMock );

        EasyMock.expect( propertiesManagerMock.getPropertiesFilePathFromSystemProperties() ).andReturn( propertiesFile );
        EasyMock.expect( propertiesManagerMock.getEncryptSwitchFromSystemProperties() ).andReturn( encryptSwich );
        EasyMock.expect( propertiesManagerMock.getKeyStorePasswordFromSystemProperties() ).andReturn( keyStorePassword );
        EasyMock.expect( propertiesManagerMock.loadPropertiesFromPropertiesFile( propertiesFile ) ).andReturn( filePropertiesMock );
        EasyMock.expect( filePropertiesMock.getProperty( "cds.keystore.properties.path" ) ).andReturn( keyStoreFileLocation );
        EasyMock.expect( propertiesManagerMock.decryptProperties( null, keyStoreFileLocation, keyStorePassword, filePropertiesMock ) ).andReturn(
                        filePropertiesMock );
        propertiesManagerMock.updateSystemProperties( filePropertiesMock );
        EasyMock.replay( propertiesManagerMock, filePropertiesMock );

        pu.loadSystemRunProperties();
    }


    @Test
    @Suite( groups = "checkintest" )
    public void testLoadEncryptedTextProperties_DecryptPasswords( )
        throws Exception
    {
        String propertiesFile = "/home/hdrdev/projects/repositories/apps/cds/main/resources/properties/cds.properties";
        String encryptSwich = null;
        String keyStoreFileLocation = "path.KeyStore";
        String keyStorePassword = "password";

        PropertiesManager propertiesManagerMock = EasyMock.createMock( PropertiesManager.class );
        Properties filePropertiesMock = EasyMock.createMock( Properties.class );
        SecretKeySpec secretKeySpecMock = null; //no encryption needed
        PropertiesUtil pu = new PropertiesUtil();
        pu.setPropertiesManager( propertiesManagerMock );

        EasyMock.expect( propertiesManagerMock.getPropertiesFilePathFromSystemProperties() ).andReturn( propertiesFile );
        EasyMock.expect( propertiesManagerMock.getEncryptSwitchFromSystemProperties() ).andReturn( encryptSwich );
        EasyMock.expect( propertiesManagerMock.getKeyStorePasswordFromSystemProperties() ).andReturn( keyStorePassword );
        EasyMock.expect( propertiesManagerMock.loadPropertiesFromPropertiesFile( propertiesFile ) ).andReturn( filePropertiesMock );
        EasyMock.expect( filePropertiesMock.getProperty( "cds.keystore.properties.path" ) ).andReturn( keyStoreFileLocation );
        EasyMock.expect( propertiesManagerMock.decryptProperties( secretKeySpecMock, keyStoreFileLocation, keyStorePassword, filePropertiesMock ) )
                        .andReturn( filePropertiesMock );
        propertiesManagerMock.updateSystemProperties( filePropertiesMock );
        EasyMock.replay( propertiesManagerMock, filePropertiesMock );

        pu.loadSystemRunProperties();
    }

}
