/*
 * 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 com.android.annotations.NonNull;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.LayoutDetector;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.XmlContext;
import java.util.Collection;
import org.w3c.dom.Element;

/** Checks whether a view hierarchy has too many views or has a suspiciously deep hierarchy */
public class TooManyViewsDetector extends LayoutDetector {

    private static final Implementation IMPLEMENTATION =
            new Implementation(TooManyViewsDetector.class, Scope.RESOURCE_FILE_SCOPE);

    /** Issue of having too many views in a single layout */
    public static final Issue TOO_MANY =
            Issue.create(
                    "TooManyViews",
                    "Layout has too many views",
                    "Using too many views in a single layout is bad for "
                            + "performance. Consider using compound drawables or other tricks for "
                            + "reducing the number of views in this layout.\n"
                            + "\n"
                            + "The maximum view count defaults to 80 but can be configured with the "
                            + "environment variable `ANDROID_LINT_MAX_VIEW_COUNT`.",
                    Category.PERFORMANCE,
                    1,
                    Severity.WARNING,
                    IMPLEMENTATION);

    /** Issue of having too deep hierarchies in layouts */
    public static final Issue TOO_DEEP =
            Issue.create(
                    "TooDeepLayout",
                    "Layout hierarchy is too deep",
                    "Layouts with too much nesting is bad for performance. "
                            + "Consider using a flatter layout (such as `RelativeLayout` or `GridLayout`)."
                            + "The default maximum depth is 10 but can be configured with the environment "
                            + "variable `ANDROID_LINT_MAX_DEPTH`.",
                    Category.PERFORMANCE,
                    1,
                    Severity.WARNING,
                    IMPLEMENTATION);

    private static final int MAX_VIEW_COUNT;
    private static final int MAX_DEPTH;

    static {
        int maxViewCount = 0;
        int maxDepth = 0;

        String countValue = System.getenv("ANDROID_LINT_MAX_VIEW_COUNT");
        if (countValue != null) {
            try {
                maxViewCount = Integer.parseInt(countValue);
            } catch (NumberFormatException e) {
                // pass: set to default below
            }
        }
        String depthValue = System.getenv("ANDROID_LINT_MAX_DEPTH");
        if (depthValue != null) {
            try {
                maxDepth = Integer.parseInt(depthValue);
            } catch (NumberFormatException e) {
                // pass: set to default below
            }
        }
        if (maxViewCount == 0) {
            maxViewCount = 80;
        }
        if (maxDepth == 0) {
            maxDepth = 10;
        }

        MAX_VIEW_COUNT = maxViewCount;
        MAX_DEPTH = maxDepth;
    }

    private int mViewCount;
    private int mDepth;
    private boolean mWarnedAboutDepth;

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

    @Override
    public void beforeCheckFile(@NonNull Context context) {
        mViewCount = mDepth = 0;
        mWarnedAboutDepth = false;
    }

    @Override
    public Collection<String> getApplicableElements() {
        return ALL;
    }

    @Override
    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
        mViewCount++;
        mDepth++;

        if (mDepth == MAX_DEPTH && !mWarnedAboutDepth) {
            // Have to record whether or not we've warned since we could have many siblings
            // at the max level and we'd warn for each one. No need to do the same thing
            // for the view count error since we'll only have view count exactly equal the
            // max just once.
            mWarnedAboutDepth = true;
            String msg =
                    String.format(
                            "`%1$s` has more than %2$d levels, bad for performance",
                            context.file.getName(), MAX_DEPTH);
            context.report(TOO_DEEP, element, context.getElementLocation(element), msg);
        }
        if (mViewCount == MAX_VIEW_COUNT) {
            String msg =
                    String.format(
                            "`%1$s` has more than %2$d views, bad for performance",
                            context.file.getName(), MAX_VIEW_COUNT);
            context.report(TOO_MANY, element, context.getElementLocation(element), msg);
        }
    }

    @Override
    public void visitElementAfter(@NonNull XmlContext context, @NonNull Element element) {
        mDepth--;
    }
}
