/*
 * 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.cauldron.bld.ivy;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.cauldron.bld.config.BldFactory;
import org.cauldron.bld.config.IBldProject;
import org.cauldron.bld.config.IBldProject.IBldBundle;
import org.cauldron.bld.core.internal.model.eclipse.SigilBundle;
import org.cauldron.bld.core.internal.model.osgi.BundleModelElement;
import org.cauldron.bld.core.licence.ILicensePolicy;
import org.cauldron.sigil.model.common.VersionRange;
import org.cauldron.sigil.model.eclipse.ISigilBundle;
import org.cauldron.sigil.model.osgi.IBundleModelElement;
import org.cauldron.sigil.model.osgi.IPackageExport;
import org.cauldron.sigil.model.osgi.IPackageImport;
import org.cauldron.sigil.model.osgi.IRequiredBundle;
import org.cauldron.sigil.repository.AbstractBundleRepository;
import org.cauldron.sigil.repository.IRepositoryVisitor;

import org.osgi.framework.Version;

public class ProjectRepository extends AbstractBundleRepository {
    private ArrayList<ISigilBundle> bundles;
    private ArrayList<ISigilBundle> wildBundles;
    private String projectFilePattern;

    /* package */ProjectRepository(String id, String projectFilePattern) {
        super(id);
        this.projectFilePattern = projectFilePattern.replaceAll("\\[sigilproject\\]",
                IBldProject.PROJECT_FILE);
    }

    @Override
    public void accept(IRepositoryVisitor visitor, int options) {
        for (ISigilBundle b : getBundles()) {
            if (!visitor.visit(b)) {
                break;
            }
        }
    }

    // override to provide fuzzy matching for wild-card exports.
    @Override
    public Collection<ISigilBundle> findAllProviders(final IPackageImport pi, int options) {
        return findProviders(pi, options, false);
    }

    @Override
    public ISigilBundle findProvider(IPackageImport pi, int options) {
        Collection<ISigilBundle> found = findProviders(pi, options, true);
        return found.isEmpty() ? null : found.iterator().next();
    }

    private Collection<ISigilBundle> findProviders(final IPackageImport pi, int options,
            boolean findFirst) {
        ArrayList<ISigilBundle> found = new ArrayList<ISigilBundle>();
        ILicensePolicy policy = findPolicy(pi);
        String name = pi.getPackageName();
        VersionRange versions = pi.getVersions();

        // find exact match(es)
        for (ISigilBundle bundle : getBundles()) {
            if (policy.accept(bundle)) {
                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
                    if (name.equals(exp.getPackageName())
                            && versions.contains(exp.getVersion())) {
                        found.add(bundle);
                        if (findFirst)
                            return found;
                    }
                }
            }
        }

        if (!found.isEmpty())
            return found;

        // find best fuzzy match
        ISigilBundle fuzzyMatch = null;
        int fuzzyLen = 0;

        for (ISigilBundle bundle : getWildBundles()) {
            if (policy.accept(bundle)) {
                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
                    String export = exp.getPackageName();
                    if (export.endsWith("*")) {
                        String export1 = export.substring(0, export.length() - 1);
                        if ((name.startsWith(export1) || export1.equals(name + "."))
                                && versions.contains(exp.getVersion())) {
                            if (export1.length() > fuzzyLen) {
                                fuzzyLen = export1.length();
                                fuzzyMatch = bundle;
                            }
                        }
                    }
                }
            }
        }

        if (fuzzyMatch != null)
            found.add(fuzzyMatch);

        return found;
    }

    private synchronized void init() {
        System.out.println("Sigil: loading Project Repository: " + projectFilePattern);

        ArrayList<File> projects = new ArrayList<File>();

        for (String pattern : projectFilePattern.split("\\s+")) {
            try {
                Collection<File> files = FindUtil.findFiles(pattern);
                if (files.isEmpty()) {
                    Log.warn("ProjectRepository: no projects match: " + pattern);
                } else {
                    projects.addAll(files);
                }
            } catch (IOException e) {
                // pattern root dir does not exist
                Log.error("ProjectRepository: " + pattern + ": " + e.getMessage());
            }
        }

        if (projects.isEmpty()) {
            throw new IllegalArgumentException(
                    "ProjectRepository: no projects found using pattern: "
                            + projectFilePattern);
        }

        bundles = new ArrayList<ISigilBundle>();

        for (File proj : projects) {
            try {
                addBundles(proj, bundles);
            } catch (IOException e) {
                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
            } catch (ParseException e) {
                Log.warn("Skipping project: " + proj + ": " + e.getMessage());
            }
        }
    }

    private List<ISigilBundle> getBundles() {
        if (bundles == null) {
            init();
        }
        return bundles;
    }

    private List<ISigilBundle> getWildBundles() {
        if (wildBundles == null) {
            wildBundles = new ArrayList<ISigilBundle>();
            for (ISigilBundle bundle : getBundles()) {
                for (IPackageExport exp : bundle.getBundleInfo().getExports()) {
                    String export = exp.getPackageName();
                    if (export.endsWith("*")) {
                        wildBundles.add(bundle);
                        break;
                    }
                }
            }
        }
        return wildBundles;
    }

    public void refresh() {
        bundles = null;
        wildBundles = null;
        notifyChange();
    }

    private void addBundles(File file, List<ISigilBundle> list) throws IOException,
            ParseException {
        URI uri = file.getCanonicalFile().toURI();
        IBldProject project = BldFactory.getProject(uri);

        for (IBldBundle bb : project.getBundles()) {
            IBundleModelElement info = new BundleModelElement();

            for (IPackageExport pexport : bb.getExports()) {
                info.addExport(pexport);
            }

            for (IPackageImport import1 : bb.getImports()) {
                IPackageImport clone = (IPackageImport) import1.clone();
                clone.setParent(null);
                info.addImport(clone);
            }

            for (IRequiredBundle require : bb.getRequires()) {
                IRequiredBundle clone = (IRequiredBundle) require.clone();
                clone.setParent(null);
                info.addRequiredBundle(clone);
            }

            info.setSymbolicName(bb.getSymbolicName());

            Version version = new Version(bb.getVersion());
            info.setVersion(version);

            ProjectBundle pb = new ProjectBundle();
            pb.setBundleInfo(info);
            pb.setId(bb.getId());

            ModuleDescriptor md = SigilParser.instance().parseDescriptor(uri.toURL());

            ModuleRevisionId mrid = md.getModuleRevisionId();
            pb.setModule(mrid.getName());
            pb.setOrg(mrid.getOrganisation());
            // XXX: should revision be configurable?
            pb.setRevision("latest." + md.getStatus());

            list.add(pb);
            Log.debug("ProjectRepository: added " + pb);
            Log.debug("ProjectRepository: exports " + bb.getExports());
        }
    }

    public static class ProjectBundle extends SigilBundle {
        private String id;
        private String module;
        private String org;
        private String revision;

        @Override
        public String toString() {
            return "ProjectBundle[" + org + "@" + module + (id == null ? "" : "$" + id)
                    + "#" + revision + "]";
        }

        public String getModule() {
            return module;
        }

        public void setModule(String module) {
            this.module = module;
        }

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getRevision() {
            return revision;
        }

        public void setRevision(String rev) {
            this.revision = rev;
        }

        public String getOrg() {
            return org;
        }

        public void setOrg(String org) {
            this.org = org;
        }
    }

}
