/*
 * Copyright (C) 2011 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.tools.lint.checks;

import static com.android.tools.lint.detector.api.LintUtils.assertionsEnabled;
import static com.android.tools.lint.detector.api.LintUtils.endsWith;

import com.android.annotations.NonNull;
import com.android.prefs.AndroidLocation;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.tools.lint.client.api.IssueRegistry;
import com.android.tools.lint.detector.api.Issue;
import com.google.common.annotations.Beta;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/** Registry which provides a list of checks to be performed on an Android project */
public class BuiltinIssueRegistry extends IssueRegistry {
    /** Folder name in the .android dir where additional detector jars are found */
    private static final String LINT_FOLDER = "lint"; //$NON-NLS-1$

    /**
     * Manifest constant for declaring an issue provider. Example:
     * Lint-Issues: foo.bar.CustomIssueRegistry
     */
    private static final String MF_LINT_REGISTRY = "Lint-Registry"; //$NON-NLS-1$

    private static final List<Issue> sIssues;

    static {
        final int initialCapacity = 97;
        List<Issue> issues = new ArrayList<Issue>(initialCapacity);

        issues.add(AccessibilityDetector.ISSUE);
        issues.add(MathDetector.ISSUE);
        issues.add(FieldGetterDetector.ISSUE);
        issues.add(SdCardDetector.ISSUE);
        issues.add(ApiDetector.UNSUPPORTED);
        issues.add(DuplicateIdDetector.CROSS_LAYOUT);
        issues.add(DuplicateIdDetector.WITHIN_LAYOUT);
        issues.add(WrongIdDetector.UNKNOWN_ID);
        issues.add(WrongIdDetector.UNKNOWN_ID_LAYOUT);
        issues.add(StateListDetector.ISSUE);
        issues.add(StyleCycleDetector.ISSUE);
        issues.add(InefficientWeightDetector.INEFFICIENT_WEIGHT);
        issues.add(InefficientWeightDetector.NESTED_WEIGHTS);
        issues.add(InefficientWeightDetector.BASELINE_WEIGHTS);
        issues.add(ScrollViewChildDetector.ISSUE);
        issues.add(DeprecationDetector.ISSUE);
        issues.add(ObsoleteLayoutParamsDetector.ISSUE);
        issues.add(MergeRootFrameLayoutDetector.ISSUE);
        issues.add(NestedScrollingWidgetDetector.ISSUE);
        issues.add(ChildCountDetector.SCROLLVIEW_ISSUE);
        issues.add(ChildCountDetector.ADAPTERVIEW_ISSUE);
        issues.add(UseCompoundDrawableDetector.ISSUE);
        issues.add(UselessViewDetector.USELESS_PARENT);
        issues.add(UselessViewDetector.USELESS_LEAF);
        issues.add(TooManyViewsDetector.TOO_MANY);
        issues.add(TooManyViewsDetector.TOO_DEEP);
        issues.add(GridLayoutDetector.ISSUE);
        issues.add(OnClickDetector.ISSUE);
        issues.add(RegistrationDetector.ISSUE);
        issues.add(HandlerDetector.ISSUE);
        issues.add(FragmentDetector.ISSUE);
        issues.add(TranslationDetector.EXTRA);
        issues.add(TranslationDetector.MISSING);
        issues.add(HardcodedValuesDetector.ISSUE);
        issues.add(Utf8Detector.ISSUE);
        issues.add(ProguardDetector.WRONGKEEP);
        issues.add(ProguardDetector.SPLITCONFIG);
        issues.add(PxUsageDetector.PX_ISSUE);
        issues.add(PxUsageDetector.DP_ISSUE);
        issues.add(TextFieldDetector.ISSUE);
        issues.add(TextViewDetector.ISSUE);
        issues.add(UnusedResourceDetector.ISSUE);
        issues.add(UnusedResourceDetector.ISSUE_IDS);
        issues.add(ExtraTextDetector.ISSUE);
        issues.add(PrivateResourceDetector.ISSUE);
        issues.add(ArraySizeDetector.INCONSISTENT);
        issues.add(HardcodedDebugModeDetector.ISSUE);
        issues.add(ManifestOrderDetector.ORDER);
        issues.add(ManifestOrderDetector.USES_SDK);
        issues.add(ManifestOrderDetector.MULTIPLE_USES_SDK);
        issues.add(ManifestOrderDetector.WRONG_PARENT);
        issues.add(ManifestOrderDetector.DUPLICATE_ACTIVITY);
        issues.add(SecurityDetector.EXPORTED_PROVIDER);
        issues.add(SecurityDetector.EXPORTED_SERVICE);
        issues.add(SecurityDetector.EXPORTED_ACTIVITY);
        issues.add(SecurityDetector.EXPORTED_RECEIVER);
        issues.add(SecurityDetector.OPEN_PROVIDER);
        issues.add(SecurityDetector.WORLD_READABLE);
        issues.add(SecurityDetector.WORLD_WRITEABLE);
        issues.add(IconDetector.GIF_USAGE);
        issues.add(IconDetector.ICON_DENSITIES);
        issues.add(IconDetector.ICON_MISSING_FOLDER);
        issues.add(IconDetector.ICON_DIP_SIZE);
        issues.add(IconDetector.ICON_EXPECTED_SIZE);
        issues.add(IconDetector.ICON_LOCATION);
        issues.add(IconDetector.DUPLICATES_NAMES);
        issues.add(IconDetector.DUPLICATES_CONFIGURATIONS);
        issues.add(IconDetector.ICON_NODPI);
        issues.add(TypographyDetector.DASHES);
        issues.add(TypographyDetector.QUOTES);
        issues.add(TypographyDetector.FRACTIONS);
        issues.add(TypographyDetector.ELLIPSIS);
        issues.add(TypographyDetector.OTHER);
        issues.add(ButtonDetector.ORDER);
        issues.add(ButtonDetector.CASE);
        issues.add(ButtonDetector.BACKBUTTON);
        issues.add(DetectMissingPrefix.MISSING_NAMESPACE);
        issues.add(OverdrawDetector.ISSUE);
        issues.add(StringFormatDetector.INVALID);
        issues.add(StringFormatDetector.ARG_COUNT);
        issues.add(StringFormatDetector.ARG_TYPES);
        issues.add(TypoDetector.ISSUE);
        issues.add(ViewTypeDetector.ISSUE);
        issues.add(WrongImportDetector.ISSUE);
        issues.add(ViewConstructorDetector.ISSUE);
        issues.add(NamespaceDetector.CUSTOMVIEW);
        issues.add(NamespaceDetector.UNUSED);
        issues.add(NamespaceDetector.TYPO);
        issues.add(AlwaysShowActionDetector.ISSUE);
        issues.add(ColorUsageDetector.ISSUE);
        issues.add(JavaPerformanceDetector.PAINT_ALLOC);
        issues.add(JavaPerformanceDetector.USE_VALUEOF);
        issues.add(JavaPerformanceDetector.USE_SPARSEARRAY);
        issues.add(SetJavaScriptEnabledDetector.ISSUE);
        issues.add(ToastDetector.ISSUE);
        issues.add(SharedPrefsDetector.ISSUE);
        issues.add(NonInternationalizedSmsDetector.ISSUE);

        assert initialCapacity >= issues.size() : issues.size();

        addCustomIssues(issues);

        sIssues = Collections.unmodifiableList(issues);

        // Check that ids are unique
        if (assertionsEnabled()) {
            Set<String> ids = new HashSet<String>();
            for (Issue issue : sIssues) {
                String id = issue.getId();
                assert !ids.contains(id) : "Duplicate id " + id; //$NON-NLS-1$
                ids.add(id);
            }
        }
    }

    /**
     * Constructs a new {@link BuiltinIssueRegistry}
     */
    public BuiltinIssueRegistry() {
    }

    @Override
    public @NonNull List<Issue> getIssues() {
        return sIssues;
    }

    /**
     * Add in custom issues registered by the user - via an environment variable
     * or in the .android/lint directory.
     */
    private static void addCustomIssues(List<Issue> issues) {
        // Look for additional detectors registered by the user, via
        // (1) an environment variable (useful for build servers etc), and
        // (2) via jar files in the .android/lint directory
        Set<File> files = null;
        try {
            File lint = new File(AndroidLocation.getFolder() + File.separator + LINT_FOLDER);
            if (lint.exists()) {
                File[] list = lint.listFiles();
                if (list != null) {
                    for (File jarFile : list) {
                        if (endsWith(jarFile.getName(), ".jar")) { //$NON-NLS-1$
                            if (files == null) {
                                files = new HashSet<File>();
                            }
                            files.add(jarFile);
                            addIssuesFromJar(jarFile, issues);
                        }
                    }
                }
            }
        } catch (AndroidLocationException e) {
            // Ignore -- no android dir, so no rules to load.
        }

        String lintClassPath = System.getenv("ANDROID_LINT_JARS"); //$NON-NLS-1$
        if (lintClassPath != null && lintClassPath.length() > 0) {
            String[] paths = lintClassPath.split(File.pathSeparator);
            for (String path : paths) {
                File jarFile = new File(path);
                if (jarFile.exists() && (files == null || !files.contains(jarFile))) {
                    addIssuesFromJar(jarFile, issues);
                }
            }
        }

    }

    /** Add the issues found in the given jar file into the given list of issues */
    private static void addIssuesFromJar(File jarFile, List<Issue> issues) {
        try {
            JarFile jarfile = new JarFile(jarFile);
            Manifest manifest = jarfile.getManifest();
            Attributes attrs = manifest.getMainAttributes();
            Object object = attrs.get(new Attributes.Name(MF_LINT_REGISTRY));
            if (object instanceof String) {
                String className = (String) object;

                // Make a class loader for this jar
                try {
                    URL url = jarFile.toURI().toURL();
                    URLClassLoader loader = new URLClassLoader(new URL[] { url },
                            BuiltinIssueRegistry.class.getClassLoader());
                    try {
                        Class<?> registryClass = Class.forName(className, true, loader);
                        IssueRegistry registry = (IssueRegistry) registryClass.newInstance();
                        for (Issue issue : registry.getIssues()) {
                            issues.add(issue);
                        }
                    } catch (Throwable e) {
                        log(e);
                    }
                } catch (MalformedURLException e) {
                    log(e);
                }
            }
        } catch (IOException e) {
            log(e);
        }
    }

    private static void log(Throwable e) {
        // TODO: Where do we log this? There's no embedding tool context here. For now,
        // just dump to the console so detector developers get some feedback on what went
        // wrong.
        e.printStackTrace();
    }

    private static Set<Issue> sAdtFixes;

    /**
     * Returns true if the given issue has an automatic IDE fix.
     *
     * @param tool the name of the tool to be checked
     * @param issue the issue to be checked
     * @return true if the given tool is known to have an automatic fix for the
     *         given issue
     */
    @Beta
    public boolean hasAutoFix(String tool, Issue issue) {
        assert tool.equals("adt"); // This is not yet a generic facility;
        // the primary purpose right now is to allow for example the HTML report
        // to give a hint to the user that some fixes don't require manual work

        if (sAdtFixes == null) {
            sAdtFixes = new HashSet<Issue>(20);
            sAdtFixes.add(InefficientWeightDetector.INEFFICIENT_WEIGHT);
            sAdtFixes.add(AccessibilityDetector.ISSUE);
            sAdtFixes.add(InefficientWeightDetector.BASELINE_WEIGHTS);
            sAdtFixes.add(HardcodedValuesDetector.ISSUE);
            sAdtFixes.add(UselessViewDetector.USELESS_LEAF);
            sAdtFixes.add(UselessViewDetector.USELESS_PARENT);
            sAdtFixes.add(PxUsageDetector.PX_ISSUE);
            sAdtFixes.add(TextFieldDetector.ISSUE);
            sAdtFixes.add(SecurityDetector.EXPORTED_SERVICE);
            sAdtFixes.add(DetectMissingPrefix.MISSING_NAMESPACE);
            sAdtFixes.add(ScrollViewChildDetector.ISSUE);
            sAdtFixes.add(ObsoleteLayoutParamsDetector.ISSUE);
            sAdtFixes.add(TypographyDetector.DASHES);
            sAdtFixes.add(TypographyDetector.ELLIPSIS);
            sAdtFixes.add(TypographyDetector.FRACTIONS);
            sAdtFixes.add(TypographyDetector.OTHER);
            sAdtFixes.add(TypographyDetector.QUOTES);
            sAdtFixes.add(UseCompoundDrawableDetector.ISSUE);
            sAdtFixes.add(ApiDetector.UNSUPPORTED);
            sAdtFixes.add(TypoDetector.ISSUE);
        }

        return sAdtFixes.contains(issue);
    }
}
