/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.harmony.xnet.provider.jsse;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;

import javax.crypto.SecretKey;

public class OpenSSLEngine {
    static {
        NativeCrypto.ENGINE_load_dynamic();
    }

    private static final Object mLoadingLock = new Object();

    /** The ENGINE's native handle. */
    private final int ctx;

    public static OpenSSLEngine getInstance(String engine) throws IllegalArgumentException {
        if (engine == null) {
            throw new NullPointerException("engine == null");
        }

        final int engineCtx;
        synchronized (mLoadingLock) {
            engineCtx = NativeCrypto.ENGINE_by_id(engine);
            if (engineCtx == 0) {
                throw new IllegalArgumentException("Unknown ENGINE id: " + engine);
            }

            NativeCrypto.ENGINE_add(engineCtx);
        }

        return new OpenSSLEngine(engineCtx);
    }

    private OpenSSLEngine(int engineCtx) {
        ctx = engineCtx;

        if (NativeCrypto.ENGINE_init(engineCtx) == 0) {
            NativeCrypto.ENGINE_free(engineCtx);
            throw new IllegalArgumentException("Could not initialize engine");
        }
    }

    public PrivateKey getPrivateKeyById(String id) throws InvalidKeyException {
        if (id == null) {
            throw new NullPointerException("id == null");
        }

        final int keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
        if (keyRef == 0) {
            return null;
        }

        OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
        try {
            return pkey.getPrivateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new InvalidKeyException(e);
        }
    }

    public SecretKey getSecretKeyById(String id, String algorithm) throws InvalidKeyException {
        if (id == null) {
            throw new NullPointerException("id == null");
        }

        final int keyRef = NativeCrypto.ENGINE_load_private_key(ctx, id);
        if (keyRef == 0) {
            return null;
        }

        OpenSSLKey pkey = new OpenSSLKey(keyRef, this, id);
        try {
            return pkey.getSecretKey(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new InvalidKeyException(e);
        }
    }

    int getEngineContext() {
        return ctx;
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            NativeCrypto.ENGINE_finish(ctx);
            NativeCrypto.ENGINE_free(ctx);
        } finally {
            super.finalize();
        }
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }

        if (!(o instanceof OpenSSLEngine)) {
            return false;
        }

        OpenSSLEngine other = (OpenSSLEngine) o;

        if (other.getEngineContext() == ctx) {
            return true;
        }

        final String id = NativeCrypto.ENGINE_get_id(ctx);
        if (id == null) {
            return false;
        }

        return id.equals(NativeCrypto.ENGINE_get_id(other.getEngineContext()));
    }

    @Override
    public int hashCode() {
        return ctx;
    }
}
