/*
 * Copyright (C) 2017 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_NS_NAME;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT;
import static com.android.SdkConstants.APPCOMPAT_LIB_ARTIFACT_ID;
import static com.android.SdkConstants.APP_PREFIX;
import static com.android.SdkConstants.ATTR_FONT_PROVIDER_AUTHORITY;
import static com.android.SdkConstants.ATTR_FONT_PROVIDER_CERTS;
import static com.android.SdkConstants.ATTR_FONT_PROVIDER_PACKAGE;
import static com.android.SdkConstants.ATTR_FONT_PROVIDER_QUERY;
import static com.android.SdkConstants.AUTO_URI;
import static com.android.SdkConstants.SUPPORT_LIB_GROUP_ID;
import static com.android.SdkConstants.TAG_FONT;
import static com.android.SdkConstants.TAG_FONT_FAMILY;
import static com.android.ide.common.repository.GradleCoordinate.COMPARE_PLUS_LOWER;
import static com.android.tools.lint.detector.api.Lint.coalesce;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.fonts.FontDetail;
import com.android.ide.common.fonts.FontFamily;
import com.android.ide.common.fonts.FontLoader;
import com.android.ide.common.fonts.FontProvider;
import com.android.ide.common.fonts.MutableFontDetail;
import com.android.ide.common.fonts.QueryParser;
import com.android.ide.common.repository.GradleCoordinate;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.AndroidVersion;
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.LintFix;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.ResourceXmlDetector;
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 com.android.tools.lint.model.LintModelLibrary;
import com.android.tools.lint.model.LintModelMavenName;
import com.android.tools.lint.model.LintModelVariant;
import com.android.utils.XmlUtils;
import com.google.common.base.Joiner;
import com.intellij.openapi.util.text.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class FontDetector extends ResourceXmlDetector {
    // TODO: Change this to the API version where we dont have to rely on appcompat for downloadable fonts loading at runtime.
    public static final int FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK =
            Integer.MAX_VALUE - 1;

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

    public static final Issue FONT_VALIDATION_WARNING =
            Issue.create(
                            "FontValidationWarning",
                            "Validation of font files",
                            "Look for problems in various font files.",
                            Category.CORRECTNESS,
                            9,
                            Severity.WARNING,
                            IMPLEMENTATION)
                    .addMoreInfo(
                            "https://developer.android.com/guide/topics/text/downloadable-fonts.html");

    public static final Issue FONT_VALIDATION_ERROR =
            Issue.create(
                            "FontValidationError",
                            "Validation of font files",
                            "Look for problems in various font files.",
                            Category.CORRECTNESS,
                            8,
                            Severity.ERROR,
                            IMPLEMENTATION)
                    .addMoreInfo(
                            "https://developer.android.com/guide/topics/text/downloadable-fonts.html");

    public static final GradleCoordinate MIN_APPSUPPORT_VERSION =
            new GradleCoordinate(SUPPORT_LIB_GROUP_ID, APPCOMPAT_LIB_ARTIFACT_ID, "26.0.0");

    private FontLoader mFontLoader;

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

    @Override
    public Collection<String> getApplicableElements() {
        return Arrays.asList(TAG_FONT_FAMILY, TAG_FONT);
    }

    @Override
    public void beforeCheckRootProject(@NonNull Context context) {
        if (mFontLoader == null) {
            mFontLoader = FontLoader.getInstance(context.getClient().getSdkHome());
        }
    }

    @Override
    public void visitElement(@NonNull XmlContext context, @NonNull Element element) {
        Attr authority = element.getAttributeNodeNS(ANDROID_URI, ATTR_FONT_PROVIDER_AUTHORITY);
        Attr query = element.getAttributeNodeNS(ANDROID_URI, ATTR_FONT_PROVIDER_QUERY);
        Attr androidPackage = element.getAttributeNodeNS(ANDROID_URI, ATTR_FONT_PROVIDER_PACKAGE);
        Attr certs = element.getAttributeNodeNS(ANDROID_URI, ATTR_FONT_PROVIDER_CERTS);

        Attr appAuthority = element.getAttributeNodeNS(AUTO_URI, ATTR_FONT_PROVIDER_AUTHORITY);
        Attr appQuery = element.getAttributeNodeNS(AUTO_URI, ATTR_FONT_PROVIDER_QUERY);
        Attr appPackage = element.getAttributeNodeNS(AUTO_URI, ATTR_FONT_PROVIDER_PACKAGE);
        Attr appCerts = element.getAttributeNodeNS(AUTO_URI, ATTR_FONT_PROVIDER_CERTS);

        Attr firstAndroidAttribute = coalesce(authority, query, androidPackage, certs);
        Attr firstAppAttribute = coalesce(appAuthority, appQuery, appPackage, appCerts);
        List<String> missingAndroidAttributes =
                findMissingAttributes(authority, query, androidPackage, certs);
        List<String> missingAppAttributes =
                findMissingAttributes(appAuthority, appQuery, appPackage, appCerts);

        Element fontTag = XmlUtils.getFirstSubTagByName(element, TAG_FONT);

        AndroidVersion minSdk = context.getMainProject().getMinSdkVersion();
        boolean downloadableFontFile = coalesce(firstAndroidAttribute, firstAppAttribute) != null;

        if (downloadableFontFile) {
            checkSupportLibraryVersion(context, element);
            if (reportMisplacedFontTag(context, fontTag)) {
                return;
            }
            if (minSdk.getApiLevel()
                    >= FUTURE_API_VERSION_WHERE_DOWNLOADABLE_FONTS_WORK_IN_FRAMEWORK) {
                reportUnexpectedAttributeNamespace(context, firstAppAttribute, ANDROID_NS_NAME);
            } else {
                reportUnexpectedAttributeNamespace(context, firstAndroidAttribute, APP_PREFIX);
            }
            FontProvider provider = reportUnknownProvider(context, authority, appAuthority);
            if (provider != null) {
                reportUnknownPackage(context, androidPackage, appPackage, provider);
                reportQueryProblem(context, query, appQuery, provider);
            }
            if (minSdk.getFeatureLevel() > AndroidVersion.VersionCodes.O_MR1) {
                reportMissingAppAttribute(
                        context,
                        firstAndroidAttribute,
                        missingAndroidAttributes,
                        ANDROID_URI,
                        ANDROID_NS_NAME,
                        provider);
            } else {
                reportMissingAppAttribute(
                        context,
                        firstAppAttribute,
                        missingAppAttributes,
                        AUTO_URI,
                        APP_PREFIX,
                        provider);
            }
        }
    }

    @NonNull
    private static List<String> findMissingAttributes(
            @Nullable Attr authority,
            @Nullable Attr query,
            @Nullable Attr packageName,
            @Nullable Attr certs) {
        if (authority != null && query != null && packageName != null && certs != null) {
            return Collections.emptyList();
        }
        List<String> missing = new ArrayList<>();
        if (authority == null) {
            missing.add(ATTR_FONT_PROVIDER_AUTHORITY);
        }
        if (query == null) {
            missing.add(ATTR_FONT_PROVIDER_QUERY);
        }
        if (packageName == null) {
            missing.add(ATTR_FONT_PROVIDER_PACKAGE);
        }
        if (certs == null) {
            missing.add(ATTR_FONT_PROVIDER_CERTS);
        }
        return missing;
    }

    private static void checkSupportLibraryVersion(
            @NonNull XmlContext context, @NonNull Element element) {
        LintModelVariant variant = context.getMainProject().getBuildVariant();
        if (variant == null) {
            return;
        }
        LintModelLibrary library =
                variant.getMainArtifact().findCompileDependency(APPCOMPAT_LIB_ARTIFACT);
        if (library == null) {
            return;
        }

        LintModelMavenName rc = library.getResolvedCoordinates();
        GradleCoordinate version =
                new GradleCoordinate(
                        SUPPORT_LIB_GROUP_ID, APPCOMPAT_LIB_ARTIFACT_ID, rc.getVersion());
        if (COMPARE_PLUS_LOWER.compare(version, MIN_APPSUPPORT_VERSION) < 0) {
            String message =
                    "Using version "
                            + version.getRevision()
                            + " of the "
                            + APPCOMPAT_LIB_ARTIFACT_ID
                            + " library. Required version for using downloadable fonts: "
                            + MIN_APPSUPPORT_VERSION.getRevision()
                            + " or higher.";
            LintFix fix = LintFix.create().data(APPCOMPAT_LIB_ARTIFACT_ID);
            reportError(context, element, message, context.getNameLocation(element), fix);
        }
    }

    private static boolean reportMisplacedFontTag(
            @NonNull XmlContext context, @Nullable Element fontTag) {
        if (fontTag == null) {
            return false;
        }
        LintFix fix =
                LintFix.create().replace().with("").range(context.getLocation(fontTag)).build();
        reportError(
                context,
                fontTag,
                "A downloadable font cannot have a `<font>` sub tag",
                context.getElementLocation(fontTag),
                fix);
        return true;
    }

    private static void reportUnexpectedAttributeNamespace(
            @NonNull XmlContext context, @Nullable Attr first, @NonNull String namespace) {
        if (first != null) {
            AndroidVersion minSdk = context.getMainProject().getMinSdkVersion();
            String message =
                    String.format(
                            "For `minSdkVersion`=%1$d only `%2$s:` attributes should be used",
                            minSdk.getApiLevel(), namespace);
            LintFix fix =
                    LintFix.create().unset(first.getNamespaceURI(), first.getLocalName()).build();
            reportWarning(context, first, message, context.getLocation(first), fix);
        }
    }

    private void reportMissingAppAttribute(
            @NonNull XmlContext context,
            @Nullable Attr firstFontAttribute,
            @NonNull List<String> missingAttributes,
            @NonNull String namespaceUri,
            @NonNull String namespacePrefix,
            @Nullable FontProvider provider) {
        if (firstFontAttribute != null && !missingAttributes.isEmpty()) {
            String message =
                    String.format(
                            "Missing required %1$s: %2$s:%3$s",
                            StringUtil.pluralize("attribute", missingAttributes.size()),
                            namespacePrefix,
                            Joiner.on(", " + namespacePrefix + ":").join(missingAttributes));
            LintFix fix = makeMissingAttributeFix(missingAttributes, namespaceUri, provider);
            Element element = firstFontAttribute.getOwnerElement();
            reportError(context, element, message, context.getElementLocation(element), fix);
        }
    }

    private LintFix makeMissingAttributeFix(
            @NonNull List<String> missingAttributes,
            @NonNull String namespaceUri,
            @Nullable FontProvider provider) {
        if (provider == null) {
            provider = mFontLoader.findOnlyKnownProvider();
        }

        LintFix.GroupBuilder fix = fix().composite();
        for (String missingAttribute : missingAttributes) {
            String value = generateNewValue(missingAttribute, provider);
            if (value == null) {
                fix.add(fix().set().todo(namespaceUri, missingAttribute).build());
            } else {
                fix.add(fix().set(namespaceUri, missingAttribute, value).build());
            }
        }
        return fix.build();
    }

    @Nullable
    private static String generateNewValue(
            @NonNull String missingAttribute, @Nullable FontProvider provider) {
        if (provider == null) {
            return null;
        }
        switch (missingAttribute) {
            case ATTR_FONT_PROVIDER_AUTHORITY:
                return provider.getAuthority();
            case ATTR_FONT_PROVIDER_PACKAGE:
                return provider.getPackageName();
            case ATTR_FONT_PROVIDER_CERTS:
                return "@array/" + provider.getCertificateResourceName();
            default:
                return null;
        }
    }

    @Nullable
    private FontProvider reportUnknownProvider(
            @NonNull XmlContext context,
            @Nullable Attr attrAuthority,
            @Nullable Attr attrAppAuthority) {
        String authority = attrAuthority != null ? attrAuthority.getValue() : null;
        String appAuthority = attrAppAuthority != null ? attrAppAuthority.getValue() : null;
        FontProvider provider = null;
        if (authority != null) {
            provider = reportUnknownProvider(context, attrAuthority, authority);
        } else if (appAuthority != null) {
            provider = reportUnknownProvider(context, attrAppAuthority, appAuthority);
        }
        return provider;
    }

    private FontProvider reportUnknownProvider(
            @NonNull XmlContext context, @NonNull Attr attrAuthority, @NonNull String authority) {
        FontProvider provider = mFontLoader.findProvider(authority);
        if (provider != null) {
            return provider;
        }
        LintFix fix = null;
        FontProvider onlyKnownProvider = mFontLoader.findOnlyKnownProvider();
        if (onlyKnownProvider != null) {
            fix =
                    fix().name("Replace with " + onlyKnownProvider.getAuthority())
                            .replace()
                            .text(authority)
                            .with(onlyKnownProvider.getAuthority())
                            .build();
        }
        reportError(
                context,
                attrAuthority,
                "Unknown font provider authority",
                context.getValueLocation(attrAuthority),
                fix);
        return null;
    }

    private static void reportUnknownPackage(
            @NonNull XmlContext context,
            @Nullable Attr attrAndroidPackage,
            @Nullable Attr attrAppPackage,
            @NonNull FontProvider provider) {
        String androidPackage = attrAndroidPackage != null ? attrAndroidPackage.getValue() : null;
        String appPackage = attrAppPackage != null ? attrAppPackage.getValue() : null;
        if (androidPackage != null && !androidPackage.equals(provider.getPackageName())) {
            reportUnknownPackage(context, attrAndroidPackage, androidPackage, provider);
        } else if (appPackage != null && !appPackage.equals(provider.getPackageName())) {
            reportUnknownPackage(context, attrAppPackage, appPackage, provider);
        }
    }

    private static void reportUnknownPackage(
            @NonNull XmlContext context,
            @NonNull Attr attrPackage,
            @NonNull String packageName,
            @NonNull FontProvider provider) {
        if (provider.getPackageName().equals(packageName)) {
            return;
        }
        LintFix fix =
                LintFix.create()
                        .name("Replace with " + provider.getPackageName())
                        .replace()
                        .text(packageName)
                        .with(provider.getPackageName())
                        .build();
        reportError(
                context,
                attrPackage,
                "Unexpected font provider package",
                context.getValueLocation(attrPackage),
                fix);
    }

    private void reportQueryProblem(
            @NonNull XmlContext context,
            @Nullable Attr androidQueryAttr,
            @Nullable Attr appQueryAttr,
            @NonNull FontProvider provider) {
        String androidQuery = androidQueryAttr != null ? androidQueryAttr.getValue() : null;
        String appQuery = appQueryAttr != null ? appQueryAttr.getValue() : null;
        if (androidQuery != null) {
            reportQueryProblem(context, androidQueryAttr, androidQuery, provider);
        } else if (appQuery != null) {
            reportQueryProblem(context, appQueryAttr, appQuery, provider);
        }
    }

    private void reportQueryProblem(
            @NonNull XmlContext context,
            @NonNull Attr queryAttr,
            @NonNull String query,
            @NonNull FontProvider provider) {
        if (query.isEmpty()) {
            LintFix fix =
                    fix().set().todo(queryAttr.getNamespaceURI(), queryAttr.getLocalName()).build();
            reportError(
                    context,
                    queryAttr,
                    "Missing provider query",
                    context.getLocation(queryAttr),
                    fix);
            return;
        }
        try {
            QueryParser.DownloadableParseResult result =
                    QueryParser.parseDownloadableFont(
                            provider.getAuthority(), XmlUtils.fromXmlAttributeValue(query));
            if (!mFontLoader.fontsLoaded()) {
                return;
            }
            for (String fontName : result.getFonts().keySet()) {
                FontFamily family = mFontLoader.findFont(provider, fontName);
                if (family == null) {
                    reportError(
                            context,
                            queryAttr,
                            "Unknown font: " + fontName,
                            context.getValueLocation(queryAttr),
                            null);
                } else {
                    for (MutableFontDetail detail : result.getFonts().get(fontName)) {
                        FontDetail best = detail.findBestMatch(family.getFonts());
                        if (best != null && detail.match(best) != 0) {
                            LintFix fix = null;
                            if (result.getFonts().size() == 1) {
                                String better = best.generateQuery(detail.getExact());

                                fix =
                                        fix().name("Replace with closest font: " + better)
                                                .set(
                                                        queryAttr.getNamespaceURI(),
                                                        queryAttr.getLocalName(),
                                                        better)
                                                .build();
                            }
                            if (detail.getExact()) {
                                reportError(
                                        context,
                                        queryAttr,
                                        "No exact match found for: " + fontName,
                                        context.getValueLocation(queryAttr),
                                        fix);
                            } else {
                                reportWarning(
                                        context,
                                        queryAttr,
                                        "No exact match found for: " + fontName,
                                        context.getValueLocation(queryAttr),
                                        fix);
                            }
                        }
                    }
                }
            }
        } catch (QueryParser.FontQueryParserError ex) {
            reportError(
                    context, queryAttr, ex.getMessage(), context.getValueLocation(queryAttr), null);
        }
    }

    private static void reportError(
            @NonNull XmlContext context,
            @NonNull Node node,
            @NonNull String message,
            @NonNull Location location,
            @Nullable LintFix fix) {
        if (!context.isEnabled(FONT_VALIDATION_ERROR)) {
            return;
        }
        context.report(FONT_VALIDATION_ERROR, node, location, message, fix);
    }

    private static void reportWarning(
            @NonNull XmlContext context,
            @NonNull Node node,
            @NonNull String message,
            @NonNull Location location,
            @Nullable LintFix fix) {
        if (!context.isEnabled(FONT_VALIDATION_WARNING)) {
            return;
        }
        context.report(FONT_VALIDATION_WARNING, node, location, message, fix);
    }
}
