/*******************************************************************************
 * Copyright (c) 2007, 2010 IBM Corporation and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: IBM Corporation - initial API and implementation
 * This file originally came from 'Eclipse Orbit' project then adapted to use 
 * in WTP and improved to use 'Manifest' to read manifest.mf, instead of reading 
 * it as a properties file.
 ******************************************************************************/
package org.eclipse.indigo.tests.jars;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.tools.ant.BuildException;
import org.eclipse.indigo.tests.utils.FullJarNameParser;
import org.eclipse.indigo.tests.utils.JARFileNameFilter;
import org.eclipse.indigo.tests.utils.ReportWriter;

/**
 * @since 3.3
 */
public class VersionTest {

    private static final String EXTENSION_JAR        = ".jar";
    private static final String EXTENSION_PACEKD_JAR = ".jar.pack.gz";
    private static final String EXTENSION_ZIP        = ".zip";
    private FullJarNameParser   nameParser           = new FullJarNameParser();
    private String              BACKSLASH            = "\\";
    private String              LITERAL_PERIOD       = BACKSLASH + ".";
    private String              ANY                  = ".*";
    private Pattern             threedots            = Pattern.compile(ANY + LITERAL_PERIOD + ANY + LITERAL_PERIOD + ANY + LITERAL_PERIOD + ANY);
    private String              outputDirectory;
    private ReportWriter        reportWriter;

    public static void main(String[] args) {

        VersionTest testlayout = new VersionTest();
        testlayout.setDirectoryToCheck("D:\\temp\\staging\\aggregate");
        try {
            testlayout.testFeatureVersions();
            testlayout.testBundleVersions();
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }

    private String directoryToCheck;


    public String getDirectoryToCheck() {
        return directoryToCheck;
    }

    public void setDirectoryToCheck(String bundleDirToCheck) {
        this.directoryToCheck = bundleDirToCheck;
    }

    private boolean testBundleVersions() throws IOException {

        String property = getDirectoryToCheck();
        if (property == null) {
            throw new BuildException("Need to set input directory to check against.");
        }
        String bundleDirectory = null;
        if (property.endsWith("/")) {
            bundleDirectory = property + "aggregate/plugins";
        }
        else {
            bundleDirectory = property + "/aggregate/plugins";
        }
        File inputdir = new File(bundleDirectory);
        if (!(inputdir.exists() && inputdir.isDirectory())) {
            throw new BuildException("bundle direcotry (" + bundleDirectory + ") must be an existing directory.");
        }
        getReportWriter().writeln(" Check for 4-part versions in Bundles");
        boolean failuresOccured = checkFilesVersions(inputdir);
        // assertFalse("Some bundles did not have 4 part version numbers", failuresOccured);
        return failuresOccured;
    }

    private boolean checkFilesVersions(File inputdir) throws IOException {
        // reset/initialize errors
        List errors = new ArrayList();
        boolean failuresOccured = false;
        File[] children = inputdir.listFiles(new JARFileNameFilter());
        int totalsize = children.length;
        int checked = 0;
        for (int i = 0; i < children.length; i++) {
            File child = children[i];
            String name = child.getName();
            // assume directory if not file
            if (child.isFile()) {
                if (name.endsWith(EXTENSION_PACEKD_JAR)) {
                    name = getBasicName(name, EXTENSION_PACEKD_JAR);
                }
                else if (name.endsWith(EXTENSION_JAR)) {
                    name = getBasicName(name, EXTENSION_JAR);
                }
                else if (name.endsWith(EXTENSION_ZIP)) {
                    name = getBasicName(name, EXTENSION_ZIP);
                }
            }
            checked++;
            boolean valid = nameParser.parse(name);
            if (!valid) {
                errors.add(name + " does not have a valid version (it is unparsable)");
            }
            else {
                String version = nameParser.getVersionString();
                Matcher matcher = threedots.matcher(version);

                if (!matcher.matches()) {
                    errors.add(name + " does not contain 4 parts");
                }
            }
        }
        getReportWriter().writeln("   Checked " + checked + " of " + totalsize + ".");
        getReportWriter().writeln("   Errors found: " + errors.size());

        if (errors.size() > 0) {
            Collections.sort(errors);
            for (Iterator iter = errors.iterator(); iter.hasNext();) {
                getReportWriter().writeln(iter.next());
            }
            failuresOccured = true;
        }
        return failuresOccured;
    }

    private String getBasicName(String fullname, String extension) {
        String result = fullname;
        int pos = fullname.lastIndexOf(extension);
        if (pos >= 0) {
            result = fullname.substring(0, pos);
        }
        return result;
    }

    public boolean testVersionsPatterns() throws IOException {
        boolean result = false;
        try {
            getReportWriter().writeln("Check 4-part version patterns");
            boolean featureFailures = testFeatureVersions();
            boolean bundleFailures = testBundleVersions();
            result = featureFailures || bundleFailures;
        }
        finally {
            getReportWriter().close();
        }
        return result;
    }

    private boolean testFeatureVersions() throws IOException {

        String property = getDirectoryToCheck();
        if (property == null) {
            throw new BuildException("Need to set input directory to check against.");
        }
        String featureDirectory = null;
        if (property.endsWith("/")) {
            featureDirectory = property + "aggregate/features";
        }
        else {
            featureDirectory = property + "/aggregate/features";
        }
        File inputdir = new File(featureDirectory);
        if (!(inputdir.exists() && inputdir.isDirectory())) {
            throw new BuildException("feature direcotry (" + featureDirectory + ") must be an existing directory.");
        }
        getReportWriter().writeln(" Check for 4-part versions in Features");
        boolean failuresOccured = checkFilesVersions(inputdir);
        // assertFalse("Some features did not have 4 part version numbers", failuresOccured);
        return failuresOccured;

    }

    public String getOutputDirectory() {
        return outputDirectory;
    }

    public void setOutputDirectory(String outputDirectory) {
        this.outputDirectory = outputDirectory;
    }

    public ReportWriter getReportWriter() {
        if (reportWriter == null) {
            String outputFilename = "versionPatternCheck.txt";
            reportWriter = new ReportWriter(getOutputDirectory(), outputFilename);
        }
        return reportWriter;
    }
}
