# 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"]
continue_conditional = ["elif", "else"]
end_conditional = ["endif"]


class Indent(_CheckFunction):
    COMMENT = re.compile(r"^\s*#")
    CONDITIONAL = re.compile(r"^\s*({})\s".format("|".join(start_conditional + end_conditional + continue_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 not self.backslash and 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]
