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

import junit.framework.TestCase;

import java.nio.ByteBuffer;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashSet;
import java.util.Set;

public class SignatureSpiTest extends TestCase {

    protected void setUp() throws Exception {
        super.setUp();
    }

    protected void tearDown() throws Exception {
        super.tearDown();
    }

    @SuppressWarnings("cast")
    public void testSignatureSpi() {
        try {
            MySignatureSpi1 ss1 = new MySignatureSpi1();
            assertNotNull(ss1);
            assertTrue(ss1 instanceof SignatureSpi);
        } catch (Exception e) {
            fail("Unexpected exception " + e.getMessage());
        }
    }

    public void testClone() {
        MySignatureSpi1 ss1 = new MySignatureSpi1();
        try {
            MySignatureSpi1 ssc1 = (MySignatureSpi1) ss1.clone();
            assertTrue(ss1 != ssc1);
        } catch (CloneNotSupportedException e) {
            fail("Unexpected CloneNotSupportedException " + e.getMessage());
        }

        MySignatureSpi2 ss2 = new MySignatureSpi2();
        try {
            ss2.clone();
            fail("CloneNotSupportedException expected ");
        } catch (CloneNotSupportedException e) {
            // expected
        }
    }

    public void testAbstractMethods() {
        MySignatureSpi1 ss1 = new MySignatureSpi1();
        byte[] b = {0, 1, 2, 3, 4, 5};
        try {
            ss1.engineGetParameter("test");
            ss1.engineInitSign(null);
            ss1.engineInitVerify(null);
            ss1.engineSetParameter("test", null);
            ss1.engineSign();
            ss1.engineUpdate(b[1]);
            ss1.engineUpdate(b, 0, b.length);
            ss1.engineVerify(b);
        } catch (Exception e) {
            fail("Unexpected exception " + e.getMessage());
        }
    }

    private boolean engineGetParametersCalled = false;
    private boolean engineGetParametersExceptionOcurred = false;

    public void testEngineGetParameters() {
        // or rather test that no UnsupportedOperationException is thrown?

        @SuppressWarnings("unused")
        Signature s = new Signature("fake") {
            protected AlgorithmParameters engineGetParameters() {
                engineGetParametersCalled = true;
                try {
                    super.engineGetParameters();
                } catch (UnsupportedOperationException e) {
                    engineGetParametersExceptionOcurred = true;
                }
                return null;
            }

            @Override
            protected Object engineGetParameter(String param)
                    throws InvalidParameterException {
                return null;
            }

            @Override
            protected void engineInitSign(PrivateKey privateKey)
                    throws InvalidKeyException {

            }

            @Override
            protected void engineInitVerify(PublicKey publicKey)
                    throws InvalidKeyException {

            }

            @Override
            protected void engineSetParameter(String param, Object value)
                    throws InvalidParameterException {

            }

            @Override
            protected byte[] engineSign() throws SignatureException {
                return null;
            }

            @Override
            protected void engineUpdate(byte b) throws SignatureException {

            }

            @Override
            protected void engineUpdate(byte[] b, int off, int len)
                    throws SignatureException {

            }

            @Override
            protected boolean engineVerify(byte[] sigBytes)
                    throws SignatureException {
                return false;
            }
        };
        // must call engineGetParameters
        s.getParameters();
        assertTrue(engineGetParametersCalled);
        assertTrue(engineGetParametersExceptionOcurred);
    }

    class MySignatureSpi1 extends SignatureSpi implements Cloneable {

        public Object engineGetParameter(String param) {
            return null;
        }

        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

        public void engineInitSign(PrivateKey privateKey) {
        }

        public void engineInitVerify(PublicKey publicKey) {
        }

        public void engineSetParameter(String param, Object value) {
        }

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

        public void engineUpdate(byte b) {
        }

        public void engineUpdate(byte[] b, int off, int len) {
        }

        public boolean engineVerify(byte[] sigBytes) {
            return false;
        }

    }

    class MySignatureSpi2 extends SignatureSpi {
        public Object engineGetParameter(String param) {
            return null;
        }

        public Object clone() throws CloneNotSupportedException {
            return super.clone();
        }

        public void engineInitSign(PrivateKey privateKey) {
        }

        public void engineInitVerify(PublicKey publicKey) {
        }

        public void engineSetParameter(String param, Object value) {
        }

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

        public void engineUpdate(byte b) {
        }

        public void engineUpdate(byte[] b, int off, int len) {
        }

        public boolean engineVerify(byte[] sigBytes) {
            return false;
        }
    }

    @SuppressWarnings("unused")
    class MySignature extends Signature {

        Set<String> calledMethods = new HashSet<String>();
        protected MySignature(String algorithm) {
            super(algorithm);
        }

        @Override
        protected Object engineGetParameter(String param)
                throws InvalidParameterException {
            methodCalled("engineGetParameter_String");
            return null;
        }


        @Override
        protected void engineInitSign(PrivateKey privateKey)
                throws InvalidKeyException {
            methodCalled("engineInitSign_PrivateKey");
        }

        @Override
        protected void engineInitVerify(PublicKey publicKey)
                throws InvalidKeyException {
            methodCalled("engineInitVerify_PublicKey");
        }

        @Override
        protected void engineSetParameter(String param, Object value)
                throws InvalidParameterException {
            methodCalled("engineSetParameter_String_Object");
        }

        @Override
        protected byte[] engineSign() throws SignatureException {
            methodCalled("engineSign");
            return null;
        }

        @Override
        protected void engineUpdate(byte b) throws SignatureException {
            methodCalled("engineUpdate_[B");
        }

        @Override
        protected void engineUpdate(byte[] b, int off, int len)
                throws SignatureException {
            methodCalled("engineUpdate_[BII");
        }

        @Override
        protected boolean engineVerify(byte[] sigBytes)
                throws SignatureException {
            methodCalled("engineVerify_[B");
            return false;
        }

        @Override
        protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
                throws InvalidKeyException {
            methodCalled("engineInitSign_PrivateKey_SecureRandom");
        }

        @Override
        protected void engineSetParameter(AlgorithmParameterSpec params)
                throws InvalidAlgorithmParameterException {
            methodCalled("engineSetParameter_AlgorithmParameterSpec");
        }

        @Override
        protected int engineSign(byte[] outbuf, int offset, int len)
                throws SignatureException {
            methodCalled("engineSign_[BII");
            return 0;
        }

        @Override
        protected void engineUpdate(ByteBuffer input) {
            methodCalled("engineUpdate_ByteBuffer");
        }

        @Override
        protected boolean engineVerify(byte[] sigBytes, int offset, int length)
                throws SignatureException {
            methodCalled("engineVerify_[BII");
            return false;
        }

        boolean wasMethodCalled(String methodName) {
            return calledMethods.contains(methodName);
        }

        void methodCalled(String methodName) {
            calledMethods.add(methodName);
        }
    }

    public void testEngineInitSign_PrivateKey_SecureRandom() {
        MySignature signature = new MySignature("fake");

        try {
            signature.initSign(null, null);
            assertTrue("SPI method not called", signature
                    .wasMethodCalled("engineInitSign_PrivateKey_SecureRandom"));
        } catch (InvalidKeyException e) {
            fail("unexpected exception: " + e);
        }
    }

    public void testEngineSetParameter()
    {
        MySignature signature = new MySignature("fake");

        try {
            signature.setParameter(null);
            assertTrue(
                    "SPI method not called",
                    signature
                            .wasMethodCalled("engineSetParameter_AlgorithmParameterSpec"));
        } catch (InvalidAlgorithmParameterException e) {
            fail("unexpected exception: " + e);
        }
    }

    public void testEngineSign_BII() {
        MySignature signature = new MySignature("fake");
        try {
            signature.initSign(new PrivateKey() {

                public String getFormat() {
                    return null;
                }

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

                public String getAlgorithm() {
                    return null;
                }
            });
        } catch (InvalidKeyException e) {
            fail("unexpected exception: " + e);
        }
        byte[] buf = new byte[10];
        try {
            signature.sign(buf, 2, 1);
            assertTrue("SPI method not called", signature
                    .wasMethodCalled("engineSign_[BII"));
        } catch (SignatureException e) {
            fail("unexpected exception: " + e);
        }
    }

    public void testEngineUpdate_ByteBuffer() {
        MySignature signature = new MySignature("fake");
        try {
            signature.initSign(new PrivateKey() {

                public String getFormat() {
                    return null;
                }

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

                public String getAlgorithm() {
                    return null;
                }
            });
        } catch (InvalidKeyException e) {
            fail("unexpected exception: " + e);
        }

        try {
            signature.update(ByteBuffer.wrap("Hello".getBytes()));
            assertTrue("SPI method not called", signature
                    .wasMethodCalled("engineUpdate_ByteBuffer"));
        } catch (SignatureException e) {
            fail("unexpected exception");
        }
    }

    public void testEngineVerify_BII() {
        MySignature signature = new MySignature("fake");

        try {
            signature.initVerify(new PublicKey() {

                public String getFormat() {
                    return null;
                }

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

                public String getAlgorithm() {
                    return null;
                }
            });
        } catch (InvalidKeyException e) {
            fail("unexpected exception");
        }

        byte[] buf = new byte[10];

        try {
            signature.verify(buf, 2, 5);
            signature.wasMethodCalled("engineVerify_[BII");
        } catch (SignatureException e) {
            fail("unexpected exception");
        }
    }

}
