/*
 * 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 org.apache.felix.deploymentadmin;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import org.osgi.framework.Version;
import org.osgi.service.deploymentadmin.DeploymentException;

/**
 * This class represents a manifest file used to describe the contents of a deployment package. It can verify the correctness of a
 * deployment package manifest and can interpret the various manifest entries and headers the OSGi specification defines.
 */
public class DeploymentPackageManifest implements Constants {
    private final Manifest m_manifest;
    private final Version m_version;
    private final List m_bundleInfos = new ArrayList();
    private final List m_resourceInfos = new ArrayList();
    private final String m_symbolicName;
    private final VersionRange m_fixPackage;

    /**
     * Creates an instance of this class.
     *
     * @param manifest The manifest file to be used as deployment manifest
     * @throws DeploymentException If the specified manifest is not a valid deployment package manifest file.
     */
    public DeploymentPackageManifest(Manifest manifest) throws DeploymentException {
        if ((manifest == null) || (manifest.getMainAttributes() == null)) {
            throw new DeploymentException(CODE_BAD_HEADER);
        }
        m_manifest = manifest;

        Attributes mainAttributes = m_manifest.getMainAttributes();

        // TODO: verify symbolic name and entry-names for valid format/chars
        m_symbolicName = getNonNullHeader(mainAttributes.getValue(DEPLOYMENTPACKAGE_SYMBOLICMAME));

        String version = getNonNullHeader(mainAttributes.getValue(DEPLOYMENTPACKAGE_VERSION));
        try {
            m_version = new Version(version);
        }
        catch (IllegalArgumentException e) {
            throw new DeploymentException(CODE_BAD_HEADER);
        }

        String fixPackage = mainAttributes.getValue(DEPLOYMENTPACKAGE_FIXPACK);
        if (fixPackage != null) {
            try {
                m_fixPackage = VersionRange.parse(fixPackage);
            }
            catch (IllegalArgumentException iae) {
                throw new DeploymentException(CODE_BAD_HEADER, "Invalid version range for header: " + DEPLOYMENTPACKAGE_FIXPACK);
            }
        }
        else {
            m_fixPackage = null;
        }

        Map entries = m_manifest.getEntries();
        for (Iterator i = entries.keySet().iterator(); i.hasNext();) {
            String key = (String) i.next();
            processEntry(key, (Attributes) entries.get(key), (m_fixPackage != null));
        }
    }

    /**
     * Determines the value of a header in the main section of the manifest.
     *
     * @param header Name of the header to retrieve.
     * @return Value of the header or null if the header was not defined.
     */
    public String getHeader(String header) {
        return m_manifest.getMainAttributes().getValue(header);
    }

    /**
     * Determines the version range a fix package can be applied to
     *
     * @return A VersionRange describing the versions the fixpackage applies to, null if the package is not a fix package.
     */
    public VersionRange getFixPackage() {
        return m_fixPackage;
    }

    /**
     * Determines the symbolic name of the deployment package.
     *
     * @return String containing the symbolic name of the deployment package.
     */
    public String getSymbolicName() {
        return m_symbolicName;
    }

    /**
     * Determines the version of the deployment package.
     * 
     * @return Version of the deployment package.
     */
    public Version getVersion() {
        return m_version;
    }

    /**
     * Determines which bundle resources are part of the deployment package, this includes customizer bundles.
     *
     * @return A List of <code>BundleInfoImpl</code> objects describing the bundle resources of the deployment package.
     */
    public List getBundleInfos() {
        return m_bundleInfos;
    }

    /**
     * Determines which processed resources are part of the deployment package.
     *
     * @return A list of <code>ResourceInfoImpl</code> objects describing the processed resources of the deployment package.
     */
    public List getResourceInfos() {
        return m_resourceInfos;
    }

    private void processEntry(String key, Attributes attributes, boolean isFixPack) throws DeploymentException {
        if (BundleInfoImpl.isBundleResource(attributes)) {
            BundleInfoImpl bundleInfo = new BundleInfoImpl(key, attributes);
            if (bundleInfo.isMissing() && !isFixPack) {
                throw new DeploymentException(CODE_BAD_HEADER, "Header '" + DEPLOYMENTPACKAGE_MISSING + "' for manifest entry '" + key + "' may only be 'true' if " + DEPLOYMENTPACKAGE_FIXPACK
                    + " manifest header is 'true'");
            }
            m_bundleInfos.add(bundleInfo);
        }
        else {
            m_resourceInfos.add(new ResourceInfoImpl(key, attributes));
        }
    }

    private String getNonNullHeader(String header) throws DeploymentException {
        if (header == null) {
            throw new DeploymentException(CODE_MISSING_HEADER);
        }
        else if ("".equals(header.trim())) {
            throw new DeploymentException(CODE_BAD_HEADER);
        }
        return header;
    }

}
