/*
 * Copyright (C) 2009 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.sdklib.internal.repository;

import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
import com.android.sdklib.internal.repository.Archive.Os;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * Scans a local SDK to find which packages are currently installed.
 */
public class LocalSdkParser {

    private Package[] mPackages;

    public LocalSdkParser() {
        // pass
    }

    /**
     * Returns the packages found by the last call to
     * {@link #parseSdk(String, SdkManager, ISdkLog)}.
     * <p/>
     * This returns initially returns null.
     * Once the parseSdk() method has been called, this returns a possibly empty but non-null array.
     */
    public Package[] getPackages() {
        return mPackages;
    }

    /**
     * Clear the internal packages list. After this call, {@link #getPackages()} will return
     * null till {@link #parseSdk(String, SdkManager, ISdkLog)} is called.
     */
    public void clearPackages() {
        mPackages = null;
    }

    /**
     * Scan the give SDK to find all the packages already installed at this location.
     * <p/>
     * Store the packages internally. You can use {@link #getPackages()} to retrieve them
     * at any time later.
     *
     * @param osSdkRoot The path to the SDK folder.
     * @param sdkManager An existing SDK manager to list current platforms and addons.
     * @param log An SDK logger object.
     * @return The packages found. Can be retrieved later using {@link #getPackages()}.
     */
    public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager, ISdkLog log) {
        ArrayList<Package> packages = new ArrayList<Package>();
        HashSet<File> visited = new HashSet<File>();

        File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);
        Package pkg = scanDoc(dir, log);
        if (pkg != null) {
            packages.add(pkg);
            visited.add(dir);
        }

        dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);
        pkg = scanTools(dir, log);
        if (pkg != null) {
            packages.add(pkg);
            visited.add(dir);
        }

        File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES);

        // for platforms, add-ons and samples, rely on the SdkManager parser
        for(IAndroidTarget target : sdkManager.getTargets()) {

            Properties props = parseProperties(new File(target.getLocation(),
                    SdkConstants.FN_SOURCE_PROP));

            try {
                if (target.isPlatform()) {
                    pkg = new PlatformPackage(target, props);

                    if (samplesRoot.isDirectory()) {
                        // Get the samples dir for a platform if it is located in the new
                        // root /samples dir. We purposely ignore "old" samples that are
                        // located under the platform dir.
                        File samplesDir = new File(target.getPath(IAndroidTarget.SAMPLES));
                        if (samplesDir.exists() && samplesDir.getParentFile().equals(samplesRoot)) {
                            Properties samplesProps = parseProperties(
                                    new File(samplesDir, SdkConstants.FN_SOURCE_PROP));
                            if (samplesProps != null) {
                                SamplePackage pkg2 = new SamplePackage(target, samplesProps);
                                packages.add(pkg2);
                            }
                            visited.add(samplesDir);
                        }
                    }
                } else {
                    pkg = new AddonPackage(target, props);
                }
            } catch (Exception e) {
                log.error(e, null);
            }

            if (pkg != null) {
                packages.add(pkg);
                visited.add(new File(target.getLocation()));
            }
        }

        scanMissingSamples(osSdkRoot, visited, packages, log);
        scanExtras(osSdkRoot, visited, packages, log);

        mPackages = packages.toArray(new Package[packages.size()]);
        return mPackages;
    }

    /**
     * Find any other directory <em>at the top level</em> that hasn't been visited yet
     * and assume they contain extra packages. This is <em>not</em> a recursive search.
     */
    private void scanExtras(String osSdkRoot,
            HashSet<File> visited,
            ArrayList<Package> packages,
            ISdkLog log) {
        File root = new File(osSdkRoot);

        if (!root.isDirectory()) {
            // This should not happen. It makes listFiles() return null so let's avoid it.
            return;
        }

        for (File dir : root.listFiles()) {
            if (dir.isDirectory() && !visited.contains(dir)) {
                Properties props = parseProperties(new File(dir, SdkConstants.FN_SOURCE_PROP));
                if (props != null) {
                    try {
                        ExtraPackage pkg = new ExtraPackage(
                                null,                       //source
                                props,                      //properties
                                dir.getName(),              //path
                                0,                          //revision
                                null,                       //license
                                "Tools",                    //description
                                null,                       //descUrl
                                Os.getCurrentOs(),          //archiveOs
                                Arch.getCurrentArch(),      //archiveArch
                                dir.getPath()               //archiveOsPath
                                );

                        // We only accept this as an extra package if it has a valid local path.
                        if (pkg.isPathValid()) {
                            packages.add(pkg);
                            visited.add(dir);
                        }
                    } catch (Exception e) {
                        log.error(e, null);
                    }
                }
            }
        }
    }

    /**
     * Find any other sub-directories under the /samples root that hasn't been visited yet
     * and assume they contain sample packages. This is <em>not</em> a recursive search.
     * <p/>
     * The use case is to find samples dirs under /samples when their target isn't loaded.
     */
    private void scanMissingSamples(String osSdkRoot,
            HashSet<File> visited,
            ArrayList<Package> packages,
            ISdkLog log) {
        File root = new File(osSdkRoot);
        root = new File(root, SdkConstants.FD_SAMPLES);

        if (!root.isDirectory()) {
            // It makes listFiles() return null so let's avoid it.
            return;
        }

        for (File dir : root.listFiles()) {
            if (dir.isDirectory() && !visited.contains(dir)) {
                Properties props = parseProperties(new File(dir, SdkConstants.FN_SOURCE_PROP));
                if (props != null) {
                    try {
                        SamplePackage pkg = new SamplePackage(dir.getAbsolutePath(), props);
                        packages.add(pkg);
                        visited.add(dir);
                    } catch (Exception e) {
                        log.error(e, null);
                    }
                }
            }
        }
    }

    /**
     * Try to find a tools package at the given location.
     * Returns null if not found.
     */
    private Package scanTools(File toolFolder, ISdkLog log) {
        // Can we find some properties?
        Properties props = parseProperties(new File(toolFolder, SdkConstants.FN_SOURCE_PROP));

        // We're not going to check that all tools are present. At the very least
        // we should expect to find adb, android and an emulator adapted to the current OS.
        Set<String> names = new HashSet<String>();
        for (File file : toolFolder.listFiles()) {
            names.add(file.getName());
        }
        if (!names.contains(SdkConstants.FN_ADB) ||
                !names.contains(SdkConstants.androidCmdName()) ||
                !names.contains(SdkConstants.FN_EMULATOR)) {
            return null;
        }

        // Create are package. use the properties if we found any.
        try {
            ToolPackage pkg = new ToolPackage(
                    null,                       //source
                    props,                      //properties
                    0,                          //revision
                    null,                       //license
                    "Tools",                    //description
                    null,                       //descUrl
                    Os.getCurrentOs(),          //archiveOs
                    Arch.getCurrentArch(),      //archiveArch
                    toolFolder.getPath()        //archiveOsPath
                    );

            return pkg;
        } catch (Exception e) {
            log.error(e, null);
        }
        return null;
    }

    /**
     * Try to find a docs package at the given location.
     * Returns null if not found.
     */
    private Package scanDoc(File docFolder, ISdkLog log) {
        // Can we find some properties?
        Properties props = parseProperties(new File(docFolder, SdkConstants.FN_SOURCE_PROP));

        // To start with, a doc folder should have an "index.html" to be acceptable.
        // We don't actually check the content of the file.
        if (new File(docFolder, "index.html").isFile()) {
            try {
                DocPackage pkg = new DocPackage(
                        null,                       //source
                        props,                      //properties
                        0,                          //apiLevel
                        null,                       //codename
                        0,                          //revision
                        null,                       //license
                        null,                       //description
                        null,                       //descUrl
                        Os.getCurrentOs(),          //archiveOs
                        Arch.getCurrentArch(),      //archiveArch
                        docFolder.getPath()         //archiveOsPath
                        );

                return pkg;
            } catch (Exception e) {
                log.error(e, null);
            }
        }

        return null;
    }

    /**
     * Parses the given file as properties file if it exists.
     * Returns null if the file does not exist, cannot be parsed or has no properties.
     */
    private Properties parseProperties(File propsFile) {
        FileInputStream fis = null;
        try {
            if (propsFile.exists()) {
                fis = new FileInputStream(propsFile);

                Properties props = new Properties();
                props.load(fis);

                // To be valid, there must be at least one property in it.
                if (props.size() > 0) {
                    return props;
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }
}
