package org.bouncycastle.jcajce.provider.symmetric.util;

import java.lang.reflect.Method;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.crypto.MacSpi;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.RC2ParameterSpec;

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.crypto.params.RC2Parameters;
// import org.bouncycastle.crypto.params.SkeinParameters;
import org.bouncycastle.jcajce.PKCS12Key;
import org.bouncycastle.jcajce.spec.AEADParameterSpec;
// Android-removed: Unsupported algorithms
// import org.bouncycastle.jcajce.spec.SkeinParameterSpec;

public class BaseMac
    extends MacSpi implements PBE
{
    private static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec");

    private Mac macEngine;

    private int scheme = PKCS12;
    private int pbeHash = SHA1;
    private int keySize = 160;

    protected BaseMac(
        Mac macEngine)
    {
        this.macEngine = macEngine;
    }

    protected BaseMac(
        Mac macEngine,
        int scheme,
        int pbeHash,
        int keySize)
    {
        this.macEngine = macEngine;
        this.scheme = scheme;
        this.pbeHash = pbeHash;
        this.keySize = keySize;
    }

    protected void engineInit(
        Key                     key,
        AlgorithmParameterSpec  params)
        throws InvalidKeyException, InvalidAlgorithmParameterException
    {
        CipherParameters        param;

        if (key == null)
        {
            throw new InvalidKeyException("key is null");
        }

        if (key instanceof PKCS12Key)
        {
            SecretKey k;
            PBEParameterSpec pbeSpec;

            try
            {
                k = (SecretKey)key;
            }
            catch (Exception e)
            {
                throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
            }

            try
            {
                pbeSpec = (PBEParameterSpec)params;
            }
            catch (Exception e)
            {
                throw new InvalidAlgorithmParameterException("PKCS12 requires a PBEParameterSpec");
            }

            if (k instanceof PBEKey && pbeSpec == null)
            {
                pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount());
            }

            int digest = SHA1;
            int keySize = 160;
            // BEGIN Android-removed: Unsupported algorithms
            // if (macEngine.getAlgorithmName().startsWith("GOST"))
            // {
            //     digest = GOST3411;
            //     keySize = 256;
            // }
            // END Android-removed: Unsupported algorithms
            // Android-changed: Adjust for missing if
            // else if (macEngine instanceof HMac)
            if (macEngine instanceof HMac)
            {
                if (!macEngine.getAlgorithmName().startsWith("SHA-1"))
                {
                    if (macEngine.getAlgorithmName().startsWith("SHA-224"))
                    {
                        digest = SHA224;
                        keySize = 224;
                    }
                    else if (macEngine.getAlgorithmName().startsWith("SHA-256"))
                    {
                        digest = SHA256;
                        keySize = 256;
                    }
                    else if (macEngine.getAlgorithmName().startsWith("SHA-384"))
                    {
                        digest = SHA384;
                        keySize = 384;
                    }
                    else if (macEngine.getAlgorithmName().startsWith("SHA-512"))
                    {
                        digest = SHA512;
                        keySize = 512;
                    }
                    // BEGIN Android-removed: Unsupported algorithms
                    // else if (macEngine.getAlgorithmName().startsWith("RIPEMD160"))
                    // {
                    //     digest = RIPEMD160;
                    //     keySize = 160;
                    // }
                    // END Android-removed: Unsupported algorithms
                    else
                    {
                        throw new InvalidAlgorithmParameterException("no PKCS12 mapping for HMAC: " + macEngine.getAlgorithmName());
                    }
                }
            }
            // TODO: add correct handling for other digests
            param = PBE.Util.makePBEMacParameters(k, PKCS12, digest, keySize, pbeSpec);
        }
        else if (key instanceof BCPBEKey)
        {
            BCPBEKey k = (BCPBEKey)key;

            if (k.getParam() != null)
            {
                param = k.getParam();
            }
            else if (params instanceof PBEParameterSpec)
            {
                param = PBE.Util.makePBEMacParameters(k, params);
            }
            else
            {
                throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
            }
        }
        else
        {
            if (params instanceof PBEParameterSpec)
            {
                throw new InvalidAlgorithmParameterException("inappropriate parameter type: " + params.getClass().getName());
            }
            param = new KeyParameter(key.getEncoded());
        }

        KeyParameter keyParam;
        if (param instanceof ParametersWithIV)
        {
            keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
        }
        else
        {
            keyParam = (KeyParameter)param;
        }

        if (params instanceof AEADParameterSpec)
        {
            AEADParameterSpec aeadSpec = (AEADParameterSpec)params;

            param = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
        }
        else if (params instanceof IvParameterSpec)
        {
            param = new ParametersWithIV(keyParam, ((IvParameterSpec)params).getIV());
        }
        // BEGIN Android-removed: Unsupported algorithms
        /*
        else if (params instanceof RC2ParameterSpec)
        {
            param = new ParametersWithIV(new RC2Parameters(keyParam.getKey(), ((RC2ParameterSpec)params).getEffectiveKeyBits()), ((RC2ParameterSpec)params).getIV());
        }
        else if (params instanceof SkeinParameterSpec)
        {
            param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(keyParam.getKey()).build();
        }
        */
        // END Android-removed: Unsupported algorithms
        else if (params == null)
        {
            param = new KeyParameter(key.getEncoded());
        }
        else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
        {
            try
            {
                Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
                Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);

                param = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
            }
            catch (Exception e)
            {
                throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
            }
        }
        else if (!(params instanceof PBEParameterSpec))
        {
            throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName());
        }

        try
        {
            macEngine.init(param);
        }
        catch (Exception e)
        {
            throw new InvalidAlgorithmParameterException("cannot initialize MAC: " + e.getMessage());
        }
    }

    protected int engineGetMacLength() 
    {
        return macEngine.getMacSize();
    }

    protected void engineReset() 
    {
        macEngine.reset();
    }

    protected void engineUpdate(
        byte    input) 
    {
        macEngine.update(input);
    }

    protected void engineUpdate(
        byte[]  input,
        int     offset,
        int     len) 
    {
        macEngine.update(input, offset, len);
    }

    protected byte[] engineDoFinal() 
    {
        byte[]  out = new byte[engineGetMacLength()];

        macEngine.doFinal(out, 0);

        return out;
    }

    private static Hashtable copyMap(Map paramsMap)
    {
        Hashtable newTable = new Hashtable();

        Iterator keys = paramsMap.keySet().iterator();
        while (keys.hasNext())
        {
            Object key = keys.next();
            newTable.put(key, paramsMap.get(key));
        }

        return newTable;
    }

    private static Class lookup(String className)
    {
        try
        {
            Class def = BaseBlockCipher.class.getClassLoader().loadClass(className);

            return def;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}
