/*
 * Copyright (C) 2013 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.SdkConstants.ANDROID_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_ID;
import static com.android.tools.lint.detector.api.LintUtils.stripIdPrefix;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.tools.lint.client.api.LintDriver;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.LayoutDetector;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.Speed;
import com.android.tools.lint.detector.api.XmlContext;
import com.android.utils.Pair;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import lombok.ast.AstVisitor;

/**
 * Checks for consistency in layouts across different resource folders
 */
public class LayoutConsistencyDetector extends LayoutDetector implements Detector.JavaScanner {

    /** Map from layout resource names to a list of files defining that resource,
     * and within each file the value is a map from string ids to the widget type
     * used by that id in this file */
    private final Map<String, List<Pair<File, Map<String, String>>>> mMap =
            Maps.newHashMapWithExpectedSize(64);

    /** Ids referenced from .java files. Only ids referenced from code are considered
     * vital to be consistent among the layout variations (others could just have ids
     * assigned to them in the layout either automatically by the layout editor or there
     * in order to support RelativeLayout constraints etc, but not be problematic
     * in findViewById calls.)
     */
    private final Set<String> mRelevantIds = Sets.newLinkedHashSetWithExpectedSize(64);

    /** Map from layout to id name to a list of locations */
    private Map<String, Map<String, List<Location>>> mLocations;

    /** Map from layout to id name to the error message to display for each */
    private Map<String, Map<String, String>> mErrorMessages;

    /** Inconsistent widget types */
    public static final Issue INCONSISTENT_IDS = Issue.create(
            "InconsistentLayout", //$NON-NLS-1$
            "Inconsistent Layouts",

            "This check ensures that a layout resource which is defined in multiple "
            + "resource folders, specifies the same set of widgets.\n"
            + "\n"
            + "This finds cases where you have accidentally forgotten to add "
            + "a widget to all variations of the layout, which could result "
            + "in a runtime crash for some resource configurations when a "
            + "`findViewById()` fails.\n"
            + "\n"
            + "There *are* cases where this is intentional. For example, you "
            + "may have a dedicated large tablet layout which adds some extra "
            + "widgets that are not present in the phone version of the layout. "
            + "As long as the code accessing the layout resource is careful to "
            + "handle this properly, it is valid. In that case, you can suppress "
            + "this lint check for the given extra or missing views, or the whole "
            + "layout",
            Category.CORRECTNESS,
            6,
            Severity.WARNING,
            new Implementation(
                    LayoutConsistencyDetector.class,
                    Scope.JAVA_AND_RESOURCE_FILES));

    /** Constructs a consistency check */
    public LayoutConsistencyDetector() {
    }

    @Override
    public boolean appliesTo(@NonNull ResourceFolderType folderType) {
        return folderType == ResourceFolderType.LAYOUT;
    }

    @NonNull
    @Override
    public Speed getSpeed() {
        return Speed.NORMAL;
    }

    @Override
    public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
        Element root = document.getDocumentElement();
        if (root != null) {
            if (context.getPhase() == 1) {
                // Map from ids to types
                Map<String,String> fileMap = Maps.newHashMapWithExpectedSize(10);
                addIds(root, fileMap);

                getFileMapList(context).add(Pair.of(context.file, fileMap));
            } else {
                String name = LintUtils.getLayoutName(context.file);
                Map<String, List<Location>> map = mLocations.get(name);
                if (map != null) {
                    lookupLocations(context, root, map);
                }
            }
        }
    }

    @NonNull
    private List<Pair<File, Map<String, String>>> getFileMapList(
            @NonNull XmlContext context) {
        String name = LintUtils.getLayoutName(context.file);
        List<Pair<File, Map<String, String>>> list = mMap.get(name);
        if (list == null) {
            list = Lists.newArrayListWithCapacity(4);
            mMap.put(name, list);
        }
        return list;
    }

    @Nullable
    private static String getId(@NonNull Element element) {
        String id = element.getAttributeNS(ANDROID_URI, ATTR_ID);
        if (id != null && !id.isEmpty() && !id.startsWith(ANDROID_PREFIX)) {
            return stripIdPrefix(id);
        }
        return null;
    }

    private static void addIds(Element element, Map<String,String> map) {
        String id = getId(element);
        if (id != null) {
            String s = stripIdPrefix(id);
            map.put(s, element.getTagName());
        }

        NodeList childNodes = element.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                addIds((Element) child, map);
            }
        }
    }

    private static void lookupLocations(
            @NonNull XmlContext context,
            @NonNull Element element,
            @NonNull Map<String, List<Location>> map) {
        String id = getId(element);
        if (id != null) {
            if (map.containsKey(id)) {
                if (context.getDriver().isSuppressed(context, INCONSISTENT_IDS, element)) {
                    map.remove(id);
                    return;
                }

                List<Location> locations = map.get(id);
                if (locations == null) {
                    locations = Lists.newArrayList();
                    map.put(id, locations);
                }
                Attr attr = element.getAttributeNodeNS(ANDROID_URI, ATTR_ID);
                assert attr != null;
                Location location = context.getLocation(attr);
                String folder = context.file.getParentFile().getName();
                location.setMessage(String.format("Occurrence in %1$s", folder));
                locations.add(location);
            }
        }

        NodeList childNodes = element.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) {
                lookupLocations(context, (Element) child, map);
            }
        }
    }

    @Override
    public void afterCheckProject(@NonNull Context context) {
        LintDriver driver = context.getDriver();
        if (driver.getPhase() == 1) {
            // First phase: gather all the ids and look for consistency issues.
            // If any are found, request location computation in phase 2 by
            // writing the ids needed for each layout in the {@link #mLocations} map.
            for (Map.Entry<String,List<Pair<File,Map<String,String>>>> entry : mMap.entrySet()) {
                String layout = entry.getKey();
                List<Pair<File, Map<String, String>>> files = entry.getValue();
                if (files.size() < 2) {
                    // No consistency problems for files that don't have resource variations
                    continue;
                }

                checkConsistentIds(layout, files);
            }

            if (mLocations != null) {
                driver.requestRepeat(this, Scope.ALL_RESOURCES_SCOPE);
            }
        } else {
            // Collect results and print
            if (!mLocations.isEmpty()) {
                reportErrors(context);
            }
        }
    }

    @NonNull
    private Set<String> stripIrrelevantIds(@NonNull Set<String> ids) {
        if (!mRelevantIds.isEmpty()) {
            Set<String> stripped = new HashSet<String>(ids);
            stripped.retainAll(mRelevantIds);
            return stripped;
        }

        return Collections.emptySet();
    }

    private void checkConsistentIds(
            @NonNull String layout,
            @NonNull List<Pair<File, Map<String, String>>> files) {
        int layoutCount = files.size();
        assert layoutCount >= 2;

        Map<File, Set<String>> idMap = getIdMap(files, layoutCount);
        Set<String> inconsistent = getInconsistentIds(idMap);
        if (inconsistent.isEmpty()) {
            return;
        }

        if (mLocations == null) {
            mLocations = Maps.newHashMap();
        }
        if (mErrorMessages == null) {
            mErrorMessages = Maps.newHashMap();
        }

        // Map from each id, to a list of layout folders it is present in
        int idCount = inconsistent.size();
        Map<String, List<String>> presence = Maps.newHashMapWithExpectedSize(idCount);
        Set<String> allLayouts = Sets.newHashSetWithExpectedSize(layoutCount);
        for (Map.Entry<File, Set<String>> entry : idMap.entrySet()) {
            File file = entry.getKey();
            String folder = file.getParentFile().getName();
            allLayouts.add(folder);
            Set<String> ids = entry.getValue();
            for (String id : ids) {
                List<String> list = presence.get(id);
                if (list == null) {
                    list = Lists.newArrayListWithExpectedSize(layoutCount);
                    presence.put(id, list);
                }
                list.add(folder);
            }
        }

        // Compute lookup maps which will be used in phase 2 to initialize actual
        // locations for the id references

        Map<String, List<Location>> map = Maps.newHashMapWithExpectedSize(idCount);
        mLocations.put(layout, map);
        Map<String, String> messages = Maps.newHashMapWithExpectedSize(idCount);
        mErrorMessages.put(layout, messages);
        for (String id : inconsistent) {
            map.put(id, null); // The locations will be filled in during the second phase

            // Determine presence description for this id
            String message;
            List<String> layouts = presence.get(id);
            Collections.sort(layouts);

            Set<String> missingSet = new HashSet<String>(allLayouts);
            missingSet.removeAll(layouts);
            List<String> missing = new ArrayList<String>(missingSet);
            Collections.sort(missing);

            if (layouts.size() < layoutCount / 2) {
                message = String.format(
                        "The id \"%1$s\" in layout \"%2$s\" is only present in the following "
                                + "layout configurations: %3$s (missing from %4$s)",
                        id, layout,
                        LintUtils.formatList(layouts, Integer.MAX_VALUE),
                        LintUtils.formatList(missing, Integer.MAX_VALUE));
            } else {
                message = String.format(
                        "The id \"%1$s\" in layout \"%2$s\" is missing from the following layout "
                                + "configurations: %3$s (present in %4$s)",
                        id, layout, LintUtils.formatList(missing, Integer.MAX_VALUE),
                        LintUtils.formatList(layouts, Integer.MAX_VALUE));
            }
            messages.put(id, message);
        }
    }

    private static Set<String> getInconsistentIds(Map<File, Set<String>> idMap) {
        Set<String> union = getAllIds(idMap);
        Set<String> inconsistent = new HashSet<String>();
        for (Map.Entry<File, Set<String>> entry : idMap.entrySet()) {
            Set<String> ids = entry.getValue();
            if (ids.size() < union.size()) {
                Set<String> missing = new HashSet<String>(union);
                missing.removeAll(ids);
                inconsistent.addAll(missing);
            }
        }
        return inconsistent;
    }

    private static Set<String> getAllIds(Map<File, Set<String>> idMap) {
        Iterator<Set<String>> iterator = idMap.values().iterator();
        assert iterator.hasNext();
        Set<String> union = new HashSet<String>(iterator.next());
        while (iterator.hasNext()) {
            union.addAll(iterator.next());
        }
        return union;
    }

    private Map<File, Set<String>> getIdMap(List<Pair<File, Map<String, String>>> files,
            int layoutCount) {
        Map<File, Set<String>> idMap = new HashMap<File, Set<String>>(layoutCount);
        for (Pair<File, Map<String, String>> pair : files) {
            File file = pair.getFirst();
            Map<String, String> typeMap = pair.getSecond();
            Set<String> ids = typeMap.keySet();
            idMap.put(file, stripIrrelevantIds(ids));
        }
        return idMap;
    }

    private void reportErrors(Context context) {
        List<String> layouts = new ArrayList<String>(mLocations.keySet());
        Collections.sort(layouts);

        for (String layout : layouts) {
            Map<String, List<Location>> locationMap = mLocations.get(layout);
            Map<String, String> messageMap = mErrorMessages.get(layout);
            assert locationMap != null;
            assert messageMap != null;

            List<String> ids = new ArrayList<String>(locationMap.keySet());
            Collections.sort(ids);
            for (String id : ids) {
                String message = messageMap.get(id);
                List<Location> locations = locationMap.get(id);
                if (locations != null) {
                    Location location = chainLocations(locations);

                    context.report(INCONSISTENT_IDS, location, message);
                }
            }
        }
    }

    @NonNull
    private static Location chainLocations(@NonNull List<Location> locations) {
        assert !locations.isEmpty();

        // Sort locations by the file parent folders
        if (locations.size() > 1) {
            Collections.sort(locations, new Comparator<Location>() {
                @Override
                public int compare(Location location1, Location location2) {
                    File file1 = location1.getFile();
                    File file2 = location2.getFile();
                    String folder1 = file1.getParentFile().getName();
                    String folder2 = file2.getParentFile().getName();
                    return folder1.compareTo(folder2);
                }
            });
            // Chain locations together
            Iterator<Location> iterator = locations.iterator();
            assert iterator.hasNext();
            Location prev = iterator.next();
            while (iterator.hasNext()) {
                Location next = iterator.next();
                prev.setSecondary(next);
                prev = next;
            }
        }

        return locations.get(0);
    }

    // ---- Implements JavaScanner ----

    @Override
    public boolean appliesToResourceRefs() {
        return true;
    }

    @Override
    public void visitResourceReference(@NonNull JavaContext context, @Nullable AstVisitor visitor,
            @NonNull lombok.ast.Node node, @NonNull String type, @NonNull String name,
            boolean isFramework) {
        if (!isFramework && type.equals(ResourceType.ID.getName())) {
            mRelevantIds.add(name);
        }
    }
}
