# See utils/checkpackagelib/readme.txt before editing this file.
# There are already dependency checks during the build, so below check
# functions don't need to check for things already checked by exploring the
# menu options using "make menuconfig" and by running "make" with appropriate
# packages enabled.

import os
import re

from checkpackagelib.base import _CheckFunction
from checkpackagelib.lib import ConsecutiveEmptyLines  # noqa: F401
from checkpackagelib.lib import EmptyLastLine          # noqa: F401
from checkpackagelib.lib import NewlineAtEof           # noqa: F401
from checkpackagelib.lib import TrailingSpace          # noqa: F401
from checkpackagelib.lib import Utf8Characters         # noqa: F401

# used in more than one check
start_conditional = ["ifdef", "ifeq", "ifndef", "ifneq"]
end_conditional = ["endif"]


class Indent(_CheckFunction):
    COMMENT = re.compile(r"^\s*#")
    CONDITIONAL = re.compile(r"^\s*({})\s".format("|".join(start_conditional + end_conditional)))
    ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")
    END_DEFINE = re.compile(r"^\s*endef\s")
    MAKEFILE_TARGET = re.compile(r"^[^# \t]+:\s")
    START_DEFINE = re.compile(r"^\s*define\s")

    def before(self):
        self.define = False
        self.backslash = False
        self.makefile_target = False

    def check_line(self, lineno, text):
        if self.START_DEFINE.search(text):
            self.define = True
            return
        if self.END_DEFINE.search(text):
            self.define = False
            return

        expect_tabs = False
        if self.define or self.backslash or self.makefile_target:
            expect_tabs = True
        if self.CONDITIONAL.search(text):
            expect_tabs = False

        # calculate for next line
        if self.ENDS_WITH_BACKSLASH.search(text):
            self.backslash = True
        else:
            self.backslash = False

        if self.MAKEFILE_TARGET.search(text):
            self.makefile_target = True
            return
        if text.strip() == "":
            self.makefile_target = False
            return

        # comment can be indented or not inside define ... endef, so ignore it
        if self.define and self.COMMENT.search(text):
            return

        if expect_tabs:
            if not text.startswith("\t"):
                return ["{}:{}: expected indent with tabs"
                        .format(self.filename, lineno),
                        text]
        else:
            if text.startswith("\t"):
                return ["{}:{}: unexpected indent with tabs"
                        .format(self.filename, lineno),
                        text]


class OverriddenVariable(_CheckFunction):
    CONCATENATING = re.compile(r"^([A-Z0-9_]+)\s*(\+|:|)=\s*\$\(\\1\)")
    END_CONDITIONAL = re.compile(r"^\s*({})".format("|".join(end_conditional)))
    OVERRIDING_ASSIGNMENTS = [':=', "="]
    START_CONDITIONAL = re.compile(r"^\s*({})".format("|".join(start_conditional)))
    VARIABLE = re.compile(r"^([A-Z0-9_]+)\s*((\+|:|)=)")
    USUALLY_OVERRIDDEN = re.compile(r"^[A-Z0-9_]+({})".format("|".join([
        r"_ARCH\s*=\s*",
        r"_CPU\s*=\s*",
        r"_SITE\s*=\s*",
        r"_SOURCE\s*=\s*",
        r"_VERSION\s*=\s*"])))

    def before(self):
        self.conditional = 0
        self.unconditionally_set = []
        self.conditionally_set = []

    def check_line(self, lineno, text):
        if self.START_CONDITIONAL.search(text):
            self.conditional += 1
            return
        if self.END_CONDITIONAL.search(text):
            self.conditional -= 1
            return

        m = self.VARIABLE.search(text)
        if m is None:
            return
        variable, assignment = m.group(1, 2)

        if self.conditional == 0:
            if variable in self.conditionally_set:
                self.unconditionally_set.append(variable)
                if assignment in self.OVERRIDING_ASSIGNMENTS:
                    return ["{}:{}: unconditional override of variable {} previously conditionally set"
                            .format(self.filename, lineno, variable),
                            text]

            if variable not in self.unconditionally_set:
                self.unconditionally_set.append(variable)
                return
            if assignment in self.OVERRIDING_ASSIGNMENTS:
                return ["{}:{}: unconditional override of variable {}"
                        .format(self.filename, lineno, variable),
                        text]
        else:
            if variable not in self.unconditionally_set:
                self.conditionally_set.append(variable)
                return
            if self.CONCATENATING.search(text):
                return ["{}:{}: immediate assignment to append to variable {}"
                        .format(self.filename, lineno, variable),
                        text]
            if self.USUALLY_OVERRIDDEN.search(text):
                return
            if assignment in self.OVERRIDING_ASSIGNMENTS:
                return ["{}:{}: conditional override of variable {}"
                        .format(self.filename, lineno, variable),
                        text]


class PackageHeader(_CheckFunction):
    def before(self):
        self.skip = False

    def check_line(self, lineno, text):
        if self.skip or lineno > 6:
            return

        if lineno in [1, 5]:
            if lineno == 1 and text.startswith("include "):
                self.skip = True
                return
            if text.rstrip() != "#" * 80:
                return ["{}:{}: should be 80 hashes ({}#writing-rules-mk)"
                        .format(self.filename, lineno, self.url_to_manual),
                        text,
                        "#" * 80]
        elif lineno in [2, 4]:
            if text.rstrip() != "#":
                return ["{}:{}: should be 1 hash ({}#writing-rules-mk)"
                        .format(self.filename, lineno, self.url_to_manual),
                        text]
        elif lineno == 6:
            if text.rstrip() != "":
                return ["{}:{}: should be a blank line ({}#writing-rules-mk)"
                        .format(self.filename, lineno, self.url_to_manual),
                        text]


class RemoveDefaultPackageSourceVariable(_CheckFunction):
    packages_that_may_contain_default_source = ["binutils", "gcc", "gdb"]

    def before(self):
        package, _ = os.path.splitext(os.path.basename(self.filename))
        package_upper = package.replace("-", "_").upper()
        self.package = package
        self.FIND_SOURCE = re.compile(
            r"^{}_SOURCE\s*=\s*{}-\$\({}_VERSION\)\.tar\.gz"
            .format(package_upper, package, package_upper))

    def check_line(self, lineno, text):
        if self.FIND_SOURCE.search(text):

            if self.package in self.packages_that_may_contain_default_source:
                return

            return ["{}:{}: remove default value of _SOURCE variable "
                    "({}#generic-package-reference)"
                    .format(self.filename, lineno, self.url_to_manual),
                    text]


class SpaceBeforeBackslash(_CheckFunction):
    TAB_OR_MULTIPLE_SPACES_BEFORE_BACKSLASH = re.compile(r"^.*(  |\t ?)\\$")

    def check_line(self, lineno, text):
        if self.TAB_OR_MULTIPLE_SPACES_BEFORE_BACKSLASH.match(text.rstrip()):
            return ["{}:{}: use only one space before backslash"
                    .format(self.filename, lineno),
                    text]


class TrailingBackslash(_CheckFunction):
    ENDS_WITH_BACKSLASH = re.compile(r"^[^#].*\\$")

    def before(self):
        self.backslash = False

    def check_line(self, lineno, text):
        last_line_ends_in_backslash = self.backslash

        # calculate for next line
        if self.ENDS_WITH_BACKSLASH.search(text):
            self.backslash = True
            self.lastline = text
            return
        self.backslash = False

        if last_line_ends_in_backslash and text.strip() == "":
            return ["{}:{}: remove trailing backslash"
                    .format(self.filename, lineno - 1),
                    self.lastline]


class TypoInPackageVariable(_CheckFunction):
    ALLOWED = re.compile(r"|".join([
        "ACLOCAL_DIR",
        "ACLOCAL_HOST_DIR",
        "ACLOCAL_PATH",
        "BR_CCACHE_INITIAL_SETUP",
        "BR_LIBC",
        "BR_NO_CHECK_HASH_FOR",
        "LINUX_EXTENSIONS",
        "LINUX_POST_PATCH_HOOKS",
        "LINUX_TOOLS",
        "LUA_RUN",
        "MKFS_JFFS2",
        "MKIMAGE_ARCH",
        "PACKAGES_PERMISSIONS_TABLE",
        "PKG_CONFIG_HOST_BINARY",
        "SUMTOOL",
        "TARGET_FINALIZE_HOOKS",
        "TARGETS_ROOTFS",
        "XTENSA_CORE_NAME"]))
    VARIABLE = re.compile(r"^([A-Z0-9_]+_[A-Z0-9_]+)\s*(\+|)=")

    def before(self):
        package, _ = os.path.splitext(os.path.basename(self.filename))
        package = package.replace("-", "_").upper()
        # linux tools do not use LINUX_TOOL_ prefix for variables
        package = package.replace("LINUX_TOOL_", "")
        # linux extensions do not use LINUX_EXT_ prefix for variables
        package = package.replace("LINUX_EXT_", "")
        self.package = package
        self.REGEX = re.compile(r"^(HOST_|ROOTFS_)?({}_[A-Z0-9_]+)".format(package))
        self.FIND_VIRTUAL = re.compile(
            r"^{}_PROVIDES\s*(\+|)=\s*(.*)".format(package))
        self.virtual = []

    def check_line(self, lineno, text):
        m = self.VARIABLE.search(text)
        if m is None:
            return

        variable = m.group(1)

        # allow to set variables for virtual package this package provides
        v = self.FIND_VIRTUAL.search(text)
        if v:
            self.virtual += v.group(2).upper().split()
            return
        for virtual in self.virtual:
            if variable.startswith("{}_".format(virtual)):
                return

        if self.ALLOWED.match(variable):
            return
        if self.REGEX.search(text) is None:
            return ["{}:{}: possible typo: {} -> *{}*"
                    .format(self.filename, lineno, variable, self.package),
                    text]


class UselessFlag(_CheckFunction):
    DEFAULT_AUTOTOOLS_FLAG = re.compile(r"^.*{}".format("|".join([
        r"_AUTORECONF\s*=\s*NO",
        r"_LIBTOOL_PATCH\s*=\s*YES"])))
    DEFAULT_GENERIC_FLAG = re.compile(r"^.*{}".format("|".join([
        r"_INSTALL_IMAGES\s*=\s*NO",
        r"_INSTALL_REDISTRIBUTE\s*=\s*YES",
        r"_INSTALL_STAGING\s*=\s*NO",
        r"_INSTALL_TARGET\s*=\s*YES"])))
    END_CONDITIONAL = re.compile(r"^\s*({})".format("|".join(end_conditional)))
    START_CONDITIONAL = re.compile(r"^\s*({})".format("|".join(start_conditional)))

    def before(self):
        self.conditional = 0

    def check_line(self, lineno, text):
        if self.START_CONDITIONAL.search(text):
            self.conditional += 1
            return
        if self.END_CONDITIONAL.search(text):
            self.conditional -= 1
            return

        # allow non-default conditionally overridden by default
        if self.conditional > 0:
            return

        if self.DEFAULT_GENERIC_FLAG.search(text):
            return ["{}:{}: useless default value ({}#"
                    "_infrastructure_for_packages_with_specific_build_systems)"
                    .format(self.filename, lineno, self.url_to_manual),
                    text]

        if self.DEFAULT_AUTOTOOLS_FLAG.search(text) and not text.lstrip().startswith("HOST_"):
            return ["{}:{}: useless default value "
                    "({}#_infrastructure_for_autotools_based_packages)"
                    .format(self.filename, lineno, self.url_to_manual),
                    text]


class VariableWithBraces(_CheckFunction):
    VARIABLE_WITH_BRACES = re.compile(r"^[^#].*[^$]\${\w+}")

    def check_line(self, lineno, text):
        if self.VARIABLE_WITH_BRACES.match(text.rstrip()):
            return ["{}:{}: use $() to delimit variables, not ${{}}"
                    .format(self.filename, lineno),
                    text]
