/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 java.security;

import java.io.IOException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import org.apache.harmony.security.fortress.Engine;


/**
 * {@code AlgorithmParameters} is an engine class which provides algorithm
 * parameters.
 */
public class AlgorithmParameters {
    /**
     * The service name.
     */
    private static final String SEVICE = "AlgorithmParameters";

    /**
     * Used to access common engine functionality.
     */
    private static Engine engine = new Engine(SEVICE);

    /**
     * The security provider.
     */
    private Provider provider;

    /**
     * The SPI implementation.
     */
    private AlgorithmParametersSpi spiImpl;

    /**
     * The security algorithm.
     */
    private String algorithm;

    /**
     * The initialization state.
     */
    private boolean initialized; // = false;

    /**
     * Constructs a new instance of {@code AlgorithmParameters} with the given
     * arguments.
     *
     * @param algPramSpi
     *            the concrete implementation.
     * @param provider
     *            the security provider.
     * @param algorithm
     *            the name of the algorithm.
     */
    protected AlgorithmParameters(AlgorithmParametersSpi algPramSpi,
            Provider provider, String algorithm) {
        this.provider = provider;
        this.algorithm = algorithm;
        this.spiImpl = algPramSpi;
    }

    /**
     * Returns a new instance of {@code AlgorithmParameters} for the specified
     * algorithm.
     *
     * @param algorithm
     *            the name of the algorithm to use.
     * @return a new instance of {@code AlgorithmParameters} for the specified
     *         algorithm.
     * @throws NoSuchAlgorithmException
     *             if the specified algorithm is not available.
     * @throws NullPointerException
     *             if {@code algorithm} is {@code null}.
     */
    public static AlgorithmParameters getInstance(String algorithm)
            throws NoSuchAlgorithmException {
        if (algorithm == null) {
            throw new NullPointerException();
        }
        synchronized (engine) {
            engine.getInstance(algorithm, null);
            return new AlgorithmParameters((AlgorithmParametersSpi) engine.spi,
                    engine.provider, algorithm);
        }
    }

    /**
     * Returns a new instance of {@code AlgorithmParameters} from the specified
     * provider for the specified algorithm.
     *
     * @param algorithm
     *            the name of the algorithm to use.
     * @param provider
     *            name of the provider of the {@code AlgorithmParameters}.
     * @return a new instance of {@code AlgorithmParameters} for the specified
     *         algorithm.
     * @throws NoSuchAlgorithmException
     *             if the specified algorithm is not available.
     * @throws NoSuchProviderException
     *             if the specified provider is not available.
     * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()}
     * @throws NullPointerException
     *             if {@code algorithm} is {@code null}.
     */
    public static AlgorithmParameters getInstance(String algorithm,
            String provider) throws NoSuchAlgorithmException,
            NoSuchProviderException {
        if (provider == null || provider.isEmpty()) {
            throw new IllegalArgumentException();
        }
        Provider p = Security.getProvider(provider);
        if (p == null) {
            throw new NoSuchProviderException(provider);
        }
        return getInstance(algorithm, p);
    }

    /**
     * Returns a new instance of {@code AlgorithmParameters} from the specified
     * provider for the specified algorithm.
     *
     * @param algorithm
     *            the name of the algorithm to use.
     * @param provider
     *            the provider of the {@code AlgorithmParameters}.
     * @return a new instance of {@code AlgorithmParameters} for the specified
     *         algorithm.
     * @throws NoSuchAlgorithmException
     *             if the specified algorithm is not available.
     * @throws NullPointerException
     *             if {@code algorithm} is {@code null}.
     * @throws IllegalArgumentException if {@code provider == null}
     */
    public static AlgorithmParameters getInstance(String algorithm,
            Provider provider) throws NoSuchAlgorithmException {
        if (provider == null) {
            throw new IllegalArgumentException();
        }
        if (algorithm == null) {
            throw new NullPointerException();
        }
        synchronized (engine) {
            engine.getInstance(algorithm, provider, null);
            return new AlgorithmParameters((AlgorithmParametersSpi) engine.spi,
                    provider, algorithm);
        }
    }

    /**
     * Returns the provider associated with this {@code AlgorithmParameters}.
     *
     * @return the provider associated with this {@code AlgorithmParameters}.
     */
    public final Provider getProvider() {
        return provider;
    }

    /**
     * Returns the name of the algorithm.
     *
     * @return the name of the algorithm.
     */
    public final String getAlgorithm() {
        return algorithm;
    }

    /**
     * Initializes this {@code AlgorithmParameters} with the specified {@code
     * AlgorithmParameterSpec}.
     *
     * @param paramSpec
     *            the parameter specification.
     * @throws InvalidParameterSpecException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized or the given {@code paramSpec} is not appropriate
     *             for initializing this {@code AlgorithmParameters}.
     */
    public final void init(AlgorithmParameterSpec paramSpec)
            throws InvalidParameterSpecException {
        if (initialized) {
            throw new InvalidParameterSpecException("Parameter has already been initialized");
        }
        spiImpl.engineInit(paramSpec);
        initialized = true;
    }

    /**
     * Initializes this {@code AlgorithmParameters} with the specified {@code
     * byte[]} using the default decoding format for parameters. The default
     * encoding format is ASN.1.
     *
     * @param params
     *            the encoded parameters.
     * @throws IOException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized, or the parameter could not be encoded.
     */
    public final void init(byte[] params) throws IOException {
        if (initialized) {
            throw new IOException("Parameter has already been initialized");
        }
        spiImpl.engineInit(params);
        initialized = true;
    }

    /**
     * Initializes this {@code AlgorithmParameters} with the specified {@code
     * byte[]} using the specified decoding format.
     *
     * @param params
     *            the encoded parameters.
     * @param format
     *            the name of the decoding format.
     * @throws IOException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized, or the parameter could not be encoded.
     */
    public final void init(byte[] params, String format) throws IOException {
        if (initialized) {
            throw new IOException("Parameter has already been initialized");
        }
        spiImpl.engineInit(params, format);
        initialized = true;
    }

    /**
     * Returns the {@code AlgorithmParameterSpec} for this {@code
     * AlgorithmParameters}.
     *
     * @param paramSpec
     *            the type of the parameter specification in which this
     *            parameters should be converted.
     * @return the {@code AlgorithmParameterSpec} for this {@code
     *         AlgorithmParameters}.
     * @throws InvalidParameterSpecException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized, or if this parameters could not be converted to
     *             the specified class.
     */
    public final <T extends AlgorithmParameterSpec> T getParameterSpec(Class<T> paramSpec)
            throws InvalidParameterSpecException {
        if (!initialized) {
            throw new InvalidParameterSpecException("Parameter has not been initialized");
        }
        return spiImpl.engineGetParameterSpec(paramSpec);
    }

    /**
     * Returns this {@code AlgorithmParameters} in their default encoding
     * format. The default encoding format is ASN.1.
     *
     * @return the encoded parameters.
     * @throws IOException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized, or if this parameters could not be encoded.
     */
    public final byte[] getEncoded() throws IOException {
        if (!initialized) {
            throw new IOException("Parameter has not been initialized");
        }
        return spiImpl.engineGetEncoded();
    }

    /**
     * Returns this {@code AlgorithmParameters} in the specified encoding
     * format.
     *
     * @param format
     *            the name of the encoding format.
     * @return the encoded parameters.
     * @throws IOException
     *             if this {@code AlgorithmParameters} has already been
     *             initialized, or if this parameters could not be encoded.
     */
    public final byte[] getEncoded(String format) throws IOException {
        if (!initialized) {
            throw new IOException("Parameter has not been initialized");
        }
        return spiImpl.engineGetEncoded(format);
    }

    /**
     * Returns a string containing a concise, human-readable description of this
     * {@code AlgorithmParameters}.
     *
     * @return a printable representation for this {@code AlgorithmParameters}.
     */
    @Override
    public final String toString() {
        if (!initialized) {
            return null;
        }
        return spiImpl.engineToString();
    }
}
