/*
 * Copyright (C) 2008 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 com.android.apkbuilder.internal;

import com.android.apkbuilder.ApkBuilder.WrongOptionException;
import com.android.apkbuilder.ApkBuilder.ApkCreationException;
import com.android.jarutils.DebugKeyProvider;
import com.android.jarutils.JavaResourceFilter;
import com.android.jarutils.SignedJarBuilder;
import com.android.jarutils.DebugKeyProvider.KeytoolException;
import com.android.prefs.AndroidLocation.AndroidLocationException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Pattern;

/**
 * Command line APK builder with signing support.
 */
public final class ApkBuilderImpl {

    private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$",
            Pattern.CASE_INSENSITIVE);
    private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",
            Pattern.CASE_INSENSITIVE);

    private final static String NATIVE_LIB_ROOT = "lib/";

    /**
     * A File to be added to the APK archive.
     * <p/>This includes the {@link File} representing the file and its path in the archive.
     */
    public final static class ApkFile {
        String archivePath;
        File file;

        ApkFile(File file, String path) {
            this.file = file;
            this.archivePath = path;
        }
    }

    private JavaResourceFilter mResourceFilter = new JavaResourceFilter();
    private boolean mVerbose = false;
    private boolean mSignedPackage = true;
    /** the optional type of the debug keystore. If <code>null</code>, the default */
    private String mStoreType = null;

    public void setVerbose(boolean verbose) {
        mVerbose = verbose;
    }

    public void setSignedPackage(boolean signedPackage) {
        mSignedPackage = signedPackage;
    }

    public void run(String[] args) throws WrongOptionException, FileNotFoundException,
            ApkCreationException {
        if (args.length < 1) {
            throw new WrongOptionException("No options specified");
        }

        // read the first args that should be a file path
        File outFile = getOutFile(args[0]);

        ArrayList<FileInputStream> zipArchives = new ArrayList<FileInputStream>();
        ArrayList<File> archiveFiles = new ArrayList<File>();
        ArrayList<ApkFile> javaResources = new ArrayList<ApkFile>();
        ArrayList<FileInputStream> resourcesJars = new ArrayList<FileInputStream>();
        ArrayList<ApkFile> nativeLibraries = new ArrayList<ApkFile>();

        int index = 1;
        do {
            String argument = args[index++];

            if ("-v".equals(argument)) {
                mVerbose = true;
            } else if ("-u".equals(argument)) {
                mSignedPackage = false;
            } else if ("-z".equals(argument)) {
                // quick check on the next argument.
                if (index == args.length)  {
                    throw new WrongOptionException("Missing value for -z");
                }

                try {
                    FileInputStream input = new FileInputStream(args[index++]);
                    zipArchives.add(input);
                } catch (FileNotFoundException e) {
                    throw new ApkCreationException("-z file is not found");
                }
            } else if ("-f". equals(argument)) {
                // quick check on the next argument.
                if (index == args.length) {
                    throw new WrongOptionException("Missing value for -f");
                }

                archiveFiles.add(getInputFile(args[index++]));
            } else if ("-rf". equals(argument)) {
                // quick check on the next argument.
                if (index == args.length) {
                    throw new WrongOptionException("Missing value for -rf");
                }

                processSourceFolderForResource(args[index++], javaResources);
            } else if ("-rj". equals(argument)) {
                // quick check on the next argument.
                if (index == args.length) {
                    throw new WrongOptionException("Missing value for -rj");
                }

                File f = new File(args[index]);
                if (f.isDirectory()) {
                    processJarFolder(args[index++], resourcesJars);
                } else if (f.isFile()) {
                    processJarFile(args[index++], resourcesJars);
                }
            } else if ("-nf".equals(argument)) {
                // quick check on the next argument.
                if (index == args.length) {
                    throw new WrongOptionException("Missing value for -nf");
                }

                String parameter = args[index++];
                File f = new File(parameter);

                // compute the offset to get the relative path
                int offset = parameter.length();
                if (parameter.endsWith(File.separator) == false) {
                    offset++;
                }

                processNativeFolder(offset, f, nativeLibraries);
            } else if ("-storetype".equals(argument)) {
                // quick check on the next argument.
                if (index == args.length) {
                    throw new WrongOptionException("Missing value for -storetype");
                }

                mStoreType  = args[index++];
            } else {
                throw new WrongOptionException("Unknown argument: " + argument);
            }
        } while (index < args.length);

        createPackage(outFile, zipArchives, archiveFiles, javaResources, resourcesJars,
                nativeLibraries);
    }


    private File getOutFile(String filepath) throws ApkCreationException {
        File f = new File(filepath);

        if (f.isDirectory()) {
            throw new ApkCreationException(filepath + " is a directory!");
        }

        if (f.exists()) { // will be a file in this case.
            if (f.canWrite() == false) {
                throw new ApkCreationException("Cannot write " + filepath);
            }
        } else {
            try {
                if (f.createNewFile() == false) {
                    throw new ApkCreationException("Failed to create " + filepath);
                }
            } catch (IOException e) {
                throw new ApkCreationException(
                        "Failed to create '" + filepath + "' : " + e.getMessage());
            }
        }

        return f;
    }

    public static File getInputFile(String filepath) throws ApkCreationException {
        File f = new File(filepath);

        if (f.isDirectory()) {
            throw new ApkCreationException(filepath + " is a directory!");
        }

        if (f.exists()) {
            if (f.canRead() == false) {
                throw new ApkCreationException("Cannot read " + filepath);
            }
        } else {
            throw new ApkCreationException(filepath + " does not exists!");
        }

        return f;
    }

    /**
     * Processes a source folder and adds its java resources to a given list of {@link ApkFile}.
     * @param folderPath the path to the source folder.
     * @param javaResources the list of {@link ApkFile} to fill.
     * @throws ApkCreationException
     */
    public static void processSourceFolderForResource(String folderPath,
            ArrayList<ApkFile> javaResources) throws ApkCreationException {

        File folder = new File(folderPath);

        if (folder.isDirectory()) {
            // file is a directory, process its content.
            File[] files = folder.listFiles();
            for (File file : files) {
                processFileForResource(file, null, javaResources);
            }
        } else {
            // not a directory? output error and quit.
            if (folder.exists()) {
                throw new ApkCreationException(folderPath + " is not a folder!");
            } else {
                throw new ApkCreationException(folderPath + " does not exist!");
            }
        }
    }

    public static void processJarFolder(String parameter, Collection<FileInputStream> resourcesJars)
            throws FileNotFoundException {
        File f = new File(parameter);
        if (f.isDirectory()) {
            String[] files = f.list(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return PATTERN_JAR_EXT.matcher(name).matches();
                }
            });

            for (String file : files) {
                String path = f.getAbsolutePath() + File.separator + file;
                processJarFile(path, resourcesJars);
            }
        } else {
            processJarFile(parameter, resourcesJars);
        }
    }

    public static void processJarFile(String jarfilePath, Collection<FileInputStream> resourcesJars)
            throws FileNotFoundException {
        FileInputStream input = new FileInputStream(jarfilePath);
        resourcesJars.add(input);
    }

    /**
     * Processes a {@link File} that could be a {@link ApkFile}, or a folder containing
     * java resources.
     * @param file the {@link File} to process.
     * @param path the relative path of this file to the source folder. Can be <code>null</code> to
     * identify a root file.
     * @param javaResources the Collection of {@link ApkFile} object to fill.
     */
    private static void processFileForResource(File file, String path,
            Collection<ApkFile> javaResources) {
        if (file.isDirectory()) {
            // a directory? we check it
            if (JavaResourceFilter.checkFolderForPackaging(file.getName())) {
                // if it's valid, we append its name to the current path.
                if (path == null) {
                    path = file.getName();
                } else {
                    path = path + "/" + file.getName();
                }

                // and process its content.
                File[] files = file.listFiles();
                for (File contentFile : files) {
                    processFileForResource(contentFile, path, javaResources);
                }
            }
        } else {
            // a file? we check it
            if (JavaResourceFilter.checkFileForPackaging(file.getName())) {
                // we append its name to the current path
                if (path == null) {
                    path = file.getName();
                } else {
                    path = path + "/" + file.getName();
                }

                // and add it to the list.
                javaResources.add(new ApkFile(file, path));
            }
        }
    }

    /**
     * Process a {@link File} for native library inclusion.
     * @param offset the length of the root folder (used to compute relative path)
     * @param f the {@link File} to process
     * @param nativeLibraries the collection to add native libraries to.
     */
    public static void processNativeFolder(int offset, File f,
            Collection<ApkFile> nativeLibraries) {
        if (f.isDirectory()) {
            File[] children = f.listFiles();

            if (children != null) {
                for (File child : children) {
                    processNativeFolder(offset, child, nativeLibraries);
                }
            }
        } else if (f.isFile()) {
            if (PATTERN_NATIVELIB_EXT.matcher(f.getName()).matches()) {
                String path = NATIVE_LIB_ROOT +
                        f.getAbsolutePath().substring(offset).replace('\\', '/');

                nativeLibraries.add(new ApkFile(f, path));
            }
        }
    }

    /**
     * Creates the application package
     * @param outFile the package file to create
     * @param zipArchives the list of zip archive
     * @param files the list of files to include in the archive
     * @param javaResources the list of java resources from the source folders.
     * @param resourcesJars the list of jar files from which to take java resources
     * @throws ApkCreationException
     */
    public void createPackage(File outFile, Iterable<? extends FileInputStream> zipArchives,
            Iterable<? extends File> files, Iterable<? extends ApkFile> javaResources,
            Iterable<? extends FileInputStream> resourcesJars,
            Iterable<? extends ApkFile> nativeLibraries) throws ApkCreationException {

        // get the debug key
        try {
            SignedJarBuilder builder;

            if (mSignedPackage) {
                System.err.println(String.format("Using keystore: %s",
                        DebugKeyProvider.getDefaultKeyStoreOsPath()));


                DebugKeyProvider keyProvider = new DebugKeyProvider(
                        null /* osKeyPath: use default */,
                        mStoreType, null /* IKeyGenOutput */);
                PrivateKey key = keyProvider.getDebugKey();
                X509Certificate certificate = (X509Certificate)keyProvider.getCertificate();

                if (key == null) {
                    throw new ApkCreationException("Unable to get debug signature key");
                }

                // compare the certificate expiration date
                if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
                    // TODO, regenerate a new one.
                    throw new ApkCreationException("Debug Certificate expired on " +
                            DateFormat.getInstance().format(certificate.getNotAfter()));
                }

                builder = new SignedJarBuilder(
                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */), key,
                        certificate);
            } else {
                builder = new SignedJarBuilder(
                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */),
                        null /* key */, null /* certificate */);
            }

            // add the archives
            for (FileInputStream input : zipArchives) {
                builder.writeZip(input, null /* filter */);
            }

            // add the single files
            for (File input : files) {
                // always put the file at the root of the archive in this case
                builder.writeFile(input, input.getName());
                if (mVerbose) {
                    System.err.println(String.format("%1$s => %2$s", input.getAbsolutePath(),
                            input.getName()));
                }
            }

            // add the java resource from the source folders.
            for (ApkFile resource : javaResources) {
                builder.writeFile(resource.file, resource.archivePath);
                if (mVerbose) {
                    System.err.println(String.format("%1$s => %2$s",
                            resource.file.getAbsolutePath(), resource.archivePath));
                }
            }

            // add the java resource from jar files.
            for (FileInputStream input : resourcesJars) {
                builder.writeZip(input, mResourceFilter);
            }

            // add the native files
            for (ApkFile file : nativeLibraries) {
                builder.writeFile(file.file, file.archivePath);
                if (mVerbose) {
                    System.err.println(String.format("%1$s => %2$s", file.file.getAbsolutePath(),
                            file.archivePath));
                }
            }

            // close and sign the application package.
            builder.close();
        } catch (KeytoolException e) {
            if (e.getJavaHome() == null) {
                throw new ApkCreationException(e.getMessage() +
                        "\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" +
                        "You can also manually execute the following command\n:" +
                        e.getCommandLine());
            } else {
                throw new ApkCreationException(e.getMessage() +
                        "\nJAVA_HOME is set to: " + e.getJavaHome() +
                        "\nUpdate it if necessary, or manually execute the following command:\n" +
                        e.getCommandLine());
            }
        } catch (AndroidLocationException e) {
            throw new ApkCreationException(e);
        } catch (Exception e) {
            throw new ApkCreationException(e);
        }
    }
}
