package org.apache.harmony.security.tests.java.security;

import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;

import junit.framework.TestCase;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyFactorySpi;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;

@TestTargetClass(KeyFactory.class)
public class KeyFactoryTest extends TestCase {

    Provider provider;
    boolean exceptionThrown;

    Provider existingProvider;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        exceptionThrown = false;

        Provider[] providers = Security.getProviders();
        if (providers.length == 0) {
            fail("no providers found");
        }

        existingProvider = providers[0];

        provider = new TestKeyFactoryProvider();
        Security.addProvider(provider);
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        Security.removeProvider(provider.getName());
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="getInstance",
            args={String.class}
    )
    public void testGetInstanceString() {
        try {
            KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
            assertNotNull(factory);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        String[] parameters = {
                "UnknownKeyFactory",
                null
        };

        Class[] exceptions = {
                NoSuchAlgorithmException.class,
                NullPointerException.class
        };

        for (int i = 0; i < parameters.length; i++) {
            String algorithm = parameters[i];
            exceptionThrown = false;
            String message = "getInstance(" + (algorithm == null ? "null" : "\"" + algorithm + "\"") + ")";
            try {
                KeyFactory.getInstance(algorithm);
            } catch (Exception e) {
                checkException(message, e, exceptions[i]);
            } finally {
                checkException(message, null, exceptions[i]);
            }
        }

    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="getInstance",
            args={String.class, String.class}
    )
    public void testGetInstanceStringString() {
        try {
            KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME, TEST_PROVIDER_NAME);
            assertNotNull(factory);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        } catch (NoSuchProviderException e) {
            fail("unexpected exception: " + e);
        }

        String[][] combinations = {
                { "UnknownKeyFactory", TEST_PROVIDER_NAME},
                { TEST_KEYFACTORY_NAME, "UnknownProvider"},
                { TEST_KEYFACTORY_NAME, existingProvider.getName() },
                { null, TEST_PROVIDER_NAME },
                { TEST_KEYFACTORY_NAME, null },
                { null, null}
        };

        Class[] exceptions = {
                NoSuchAlgorithmException.class,
                NoSuchProviderException.class,
                NoSuchAlgorithmException.class,
                NullPointerException.class,
                IllegalArgumentException.class,
                IllegalArgumentException.class
        };

        for (int i = 0; i < combinations.length; i++) {
            String[] combination = combinations[i];
            String message = "getInstance(\"" + combination[0] + "\", \"" + combination[1] + "\")";
            exceptionThrown = false;
            try {
                KeyFactory.getInstance(combination[0], combination[1]);
            } catch (Exception e) {
                checkException(message, e, exceptions[i]);
            } finally {
                checkException(message, null, exceptions[i]);
            }
        }
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="getInstance",
            args={String.class, Provider.class}
    )
    public void testGetInstanceStringProvider() {
        try {
            KeyFactory factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME, provider);
            assertNotNull(factory);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        String[] algorithms = {
                "UnknownKeyFactory",
                null,
                TEST_KEYFACTORY_NAME,
                TEST_KEYFACTORY_NAME
        };

        Provider[] providers = {
                provider,
                provider,
                existingProvider,
                null
        };

        Class[] exceptions = {
                NoSuchAlgorithmException.class,
                NullPointerException.class,
                NoSuchAlgorithmException.class,
                IllegalArgumentException.class
        };

        for (int i = 0; i < algorithms.length; i++) {
            String algorithm = algorithms[i];
            Provider provider = providers[i];
            String message = "getInstance(" +
                (algorithm == null ? "null" : "\"" + algorithm + "\"") +
                ", " +
                (provider == null ? "null" : "provider");
            exceptionThrown = false;
            try {
                KeyFactory.getInstance(algorithm, provider);
            } catch (Exception e) {
                checkException(message, e, exceptions[i]);
            } finally {
                checkException(message, null, exceptions[i]);
            }

        }
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="generatePublic",
            args={KeySpec.class}
    )
    public void testGeneratePublic() {
        KeyFactory factory = null;
        try {
            factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        assertNotNull(factory);

        try {
            TestPublicKey key = new TestPublicKey();
            TestPublicKeySpec keySpec = new TestPublicKeySpec(key);
            PublicKey publicKey = factory.generatePublic(keySpec);
            assertNotNull(publicKey);
            assertTrue(Arrays.equals(key.encoded, publicKey.getEncoded()));
        } catch (InvalidKeySpecException e) {
            fail("unexpected exception: " + e);
        }

        KeySpec[] keySpecs = {
                new TestPrivateKeySpec(new TestPrivateKey()),
                null,
                new DSAPublicKeySpec(null, null, null, null)
        };

        Class[] exceptions = {
                InvalidKeySpecException.class,
                NullPointerException.class,
                InvalidKeySpecException.class
        };

        for (int i = 0; i < keySpecs.length; i++) {
            KeySpec keySpec = keySpecs[i];
            String message = "generatePublic(" +
                (keySpec == null ? "null" : keySpec.toString()) + ")";

            try {
                PublicKey generatePublic = factory.generatePublic(keySpec);
                assertNotNull(generatePublic);
            } catch (Exception e) {
                checkException(message, e, exceptions[i]);
            } finally {
                checkException(message, null, exceptions[i]);
            }
        }
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="generatePrivate",
            args={KeySpec.class}
    )
    public void testGeneratePrivate() {
        KeyFactory factory = null;
        try {
            factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        assertNotNull(factory);

        try {
            TestPrivateKey key = new TestPrivateKey();
            TestPrivateKeySpec keySpec = new TestPrivateKeySpec(key);
            PrivateKey privateKey = factory.generatePrivate(keySpec);
            assertNotNull(privateKey);
            assertTrue(Arrays.equals(key.getEncoded(), privateKey.getEncoded()));
        } catch (InvalidKeySpecException e) {
            fail("unexpected exception: " + e);
        }

        KeySpec[] keySpecs = {
                new TestPublicKeySpec(new TestPublicKey()),
                null,
                new DSAPublicKeySpec(null, null, null, null)
        };

        Class[] exceptions = {
                InvalidKeySpecException.class,
                NullPointerException.class,
                InvalidKeySpecException.class
        };

        for (int i = 0; i < keySpecs.length; i++) {
            KeySpec keySpec = keySpecs[i];
            exceptionThrown = false;
            String message = "generatePrivate(" +
                (keySpec == null ? "null" : keySpec.toString()) + ")";
            try {
                factory.generatePrivate(keySpec);
            } catch (Exception e) {
                checkException(message, e, exceptions[i]);
            } finally {
                checkException(message, null, exceptions[i]);
            }
        }
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="getKeySpec",
            args={Key.class, Class.class}
    )
    public void testGetKeySpec() {
        KeyFactory factory = null;
        try {
            factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        assertNotNull(factory);

        {
            Key[] keys = {
                    new TestPrivateKey(),
                    new TestPublicKey(),
                    new TestPrivateKey(new byte[] { 42, 41, 40 }),
                    new TestPublicKey(new byte[] { 40, 41, 42 })
            };

            Class[] keySpecs = {
                    TestPrivateKeySpec.class,
                    TestPublicKeySpec.class,
                    TestPrivateKeySpec.class,
                    TestPublicKeySpec.class,
            };

            for (int i = 0; i < keys.length; i++) {
                Key key = keys[i];
                Class keySpec = keySpecs[i];
                String message = "getKeySpec(" + key.toString() + ", " + keySpec.toString() + ")";
                try {
                    KeySpec spec = factory.getKeySpec(key, keySpec);
                    assertNotNull(spec);
                    assertTrue(spec.getClass() == keySpec);
                } catch (InvalidKeySpecException e) {
                    fail("unexpected exception: " + e);
                }
            }
        }

        {
            Key[] keys = {
                    new AnotherKey(),
                    null,
                    new TestPrivateKey(),
                    null,
            };

            Class[] keySpecs = {
                    KeySpec.class,
                    TestPrivateKeySpec.class,
                    null,
                    null,
            };

            Class[] exceptions = {
                    InvalidKeySpecException.class,
                    NullPointerException.class,
                    InvalidKeySpecException.class,
                    NullPointerException.class
            };

            for (int i = 0; i < keys.length; i++) {
                Key key = keys[i];
                Class keySpec = keySpecs[i];
                exceptionThrown = false;
                String message = "getKeySpec(" +
                    (key == null ? "null" : key.toString()) +
                    ", " +
                    (keySpec == null ? "null" : keySpec.toString()) + ")";
                try {
                    factory.getKeySpec(key, keySpec);
                } catch (Exception e) {
                    checkException(message, e, exceptions[i]);
                } finally {
                    checkException(message, null, exceptions[i]);
                }

            }
        }
    }

    @SuppressWarnings("unchecked")
    @TestTargetNew(
            level=TestLevel.COMPLETE,
            method="translateKey",
            args={Key.class}
    )
    public void testTranslateKey() {
        KeyFactory factory = null;
        try {
            factory = KeyFactory.getInstance(TEST_KEYFACTORY_NAME);
        } catch (NoSuchAlgorithmException e) {
            fail("unexpected exception: " + e);
        }

        assertNotNull(factory);

        {
            Key[] keys = {
                    new TestPrivateKey(),
                    new TestPublicKey()
            };

            Class[] translated = {
                    TestPublicKey.class,
                    TestPrivateKey.class
            };

            for (int i = 0; i < keys.length; i++) {
                Key key = keys[i];
                Class translate = translated[i];
                try {
                    Key translateKey = factory.translateKey(key);
                    assertNotNull(translateKey);
                    assertEquals(translate, translateKey.getClass());
                } catch (InvalidKeyException e) {
                    fail("unexpected exception: " + e);
                }
            }
        }

        {
            Key[] keys = {
                    new AnotherKey(),
                    null
            };

            Class[] exceptions = {
                    InvalidKeyException.class,
                    NullPointerException.class
            };

            for (int i = 0; i < keys.length; i++) {
                Key key = keys[i];
                String message = "translateKey(" +
                    (key == null ? "null" : key.toString()) + ")";
                exceptionThrown = false;
                try {
                    factory.translateKey(key);
                } catch (Exception e) {
                    checkException(message, e, exceptions[i]);
                } finally {
                    checkException(message, null, exceptions[i]);
                }
            }
        }
    }

    private static final String TEST_PROVIDER_NAME = "TestKeyFactoryProvider";
    private static final String TEST_KEYFACTORY_NAME = "TestKeyFactory";

    static class TestKeyFactoryProvider extends Provider {

        protected TestKeyFactoryProvider() {
            super(TEST_PROVIDER_NAME, 1.1, "Test KeyFactory Provider");
            put("KeyFactory." + TEST_KEYFACTORY_NAME, TestKeyFactorySpi.class.getName());
        }
    }

    public static class TestKeyFactorySpi extends KeyFactorySpi {

        @Override
        protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
                throws InvalidKeySpecException {
            if (TestPrivateKeySpec.class == keySpec.getClass()) {
                return new TestPrivateKey(((TestPrivateKeySpec)keySpec).encoded);
            }

            throw new InvalidKeySpecException();
        }

        @Override
        protected PublicKey engineGeneratePublic(KeySpec keySpec)
                throws InvalidKeySpecException {
            if (TestPublicKeySpec.class == keySpec.getClass()) {
                return new TestPublicKey(((TestPublicKeySpec)keySpec).encoded);
            }
            throw new InvalidKeySpecException();
        }

        @Override
        protected <T extends KeySpec> T engineGetKeySpec(Key key,
                Class<T> keySpec) throws InvalidKeySpecException {

            if (key == null) {
                throw new NullPointerException();
            }

            Constructor<T> constructor = null;
            if (TestPrivateKeySpec.class == keySpec) {
                try {
                    constructor = keySpec.getConstructor(TestPrivateKey.class);
                } catch (SecurityException e) {
                    throw new InvalidKeySpecException(e);
                } catch (NoSuchMethodException e) {
                    throw new InvalidKeySpecException(e);
                }
            } else if (TestPublicKeySpec.class == keySpec) {
                try {
                    constructor = keySpec.getConstructor(TestPublicKey.class);
                } catch (SecurityException e) {
                    throw new InvalidKeySpecException(e);
                } catch (NoSuchMethodException e) {
                    throw new InvalidKeySpecException(e);
                }
            }

            if (constructor == null) {
                throw new InvalidKeySpecException();
            }

            try {
                return constructor.newInstance(key);
            } catch (IllegalArgumentException e) {
                throw new InvalidKeySpecException(e);
            } catch (InstantiationException e) {
                throw new InvalidKeySpecException(e);
            } catch (IllegalAccessException e) {
                throw new InvalidKeySpecException(e);
            } catch (InvocationTargetException e) {
                throw new InvalidKeySpecException(e);
            }
        }

        @Override
        protected Key engineTranslateKey(Key key) throws InvalidKeyException {
            if (TestPrivateKey.class == key.getClass()) {
                return new TestPublicKey();
            } else if (TestPublicKey.class == key.getClass()) {
                return new TestPrivateKey();
            }
            throw new InvalidKeyException();
        }

    }

    static class TestPrivateKeySpec implements KeySpec {
        @SuppressWarnings("unused")
        private final byte[] encoded;

        public TestPrivateKeySpec(TestPrivateKey key) {
            this.encoded = key.getEncoded();
        }
    }

    static class TestPublicKeySpec implements KeySpec {
        @SuppressWarnings("unused")
        private final byte[] encoded;

        public TestPublicKeySpec(TestPublicKey key) {
            this.encoded = key.getEncoded();
        }
    }

    static class TestPrivateKey implements PrivateKey {

        private final byte[] encoded;

        public TestPrivateKey() {
            encoded = new byte[] {3, 4, 5};
        }

        public TestPrivateKey(byte[] encoded) {
            this.encoded = encoded;
        }

        public String getAlgorithm() {
            return "TestPrivateKey";
        }

        public byte[] getEncoded() {
            return encoded;
        }

        public String getFormat() {
            return "TestFormat";
        }
    }

    static class TestPublicKey implements PublicKey {

        private final byte[] encoded;

        public TestPublicKey() {
            encoded = new byte[] {3, 4, 5};
        }

        public TestPublicKey(byte[] encoded) {
            this.encoded = encoded;
        }

        public String getAlgorithm() {
            return "TestPublicKey";
        }

        public byte[] getEncoded() {
            return encoded;
        }

        public String getFormat() {
            return "TestFormat";
        }
    }

    static class AnotherKey implements Key {

        public String getAlgorithm() {
            return "AnotherKey";
        }

        public byte[] getEncoded() {
            return null;
        }

        public String getFormat() {
            return "AnotherFormat";
        }

    }

    private void checkException(String message, Exception thrown, Class<? extends Exception> expected) {
        if (thrown == null) {
            if (!exceptionThrown) {
                fail(message + ", expected " + expected.getName());
            }
        } else if (expected == thrown.getClass()) {
            exceptionThrown = true;
            // ok
        } else {
            exceptionThrown = true;
            fail(message + ", unexpected exception: " + thrown + ", expected: " + expected.getName());
        }
    }

}
