# Copyright 2021 Google LLC
#
# 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
#
#      https://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.


# Run test product configuration and verify its result.
# The main configuration file is product.rbc.
# It inherits part1.rbc and also includes include1.rbc
# TODO(asmundak): more tests are needed to verify that:
#  * multi-level inheritance works as expected
#  * all runtime functions (wildcard, regex, etc.) work

load("//build/make/core:product_config.rbc", "rblf")
load(":input_variables.rbc", input_variables_init = "init")
load(":product.rbc", "init")
load(":board.rbc", board_init = "init")
load(":board_input_vars.rbc", board_input_vars_init = "init")

def assert_eq(expected, actual):
    if expected != actual:
        fail("Expected '%s', got '%s'" % (expected, actual))

# Unit tests for non-trivial runtime functions
assert_eq("", rblf.mkstrip(" \n \t    "))
assert_eq("a b c", rblf.mkstrip("  a b   \n  c \t"))
assert_eq(1, rblf.mkstrip(1))

assert_eq("b1 b2", rblf.mksubst("a", "b", "a1 a2"))
assert_eq(["b1", "x2"], rblf.mksubst("a", "b", ["a1", "x2"]))

assert_eq("ABcdYZ", rblf.mkpatsubst("ab%yz", "AB%YZ", "abcdyz"))
assert_eq("bcz", rblf.mkpatsubst("a%z", "A%Z", "bcz"))
assert_eq(["Ay", "Az"], rblf.mkpatsubst("a%", "A%", ["ay", "az"]))
assert_eq("AcZ bcz", rblf.mkpatsubst("a%z", "A%Z", "acz  bcz"))
assert_eq("Abcd", rblf.mkpatsubst("a%", "A%", "abcd"))
assert_eq("abcZ", rblf.mkpatsubst("%z", "%Z", "abcz"))
assert_eq("azx b", rblf.mkpatsubst("az", "AZ", "azx  b"))
assert_eq(["azx", "b"], rblf.mkpatsubst("az", "AZ", ["azx", "b"]))
assert_eq("ABC", rblf.mkpatsubst("abc", "ABC", "abc"))
assert_eq(["%/foo"], rblf.mkpatsubst("%", "\\%/%", ["foo"]))
assert_eq(["foo/%"], rblf.mkpatsubst("%", "%/%", ["foo"]))
assert_eq(["from/a:to/a", "from/b:to/b"], rblf.product_copy_files_by_pattern("from/%", "to/%", "a b"))

assert_eq([], rblf.filter(["a", "", "b"], "f"))
assert_eq(["", "b"], rblf.filter_out(["a", "" ], ["a", "", "b"] ))

assert_eq("foo.c no_folder", rblf.notdir(["src/foo.c", "no_folder"]))
assert_eq("foo.c no_folder", rblf.notdir("src/foo.c no_folder"))
assert_eq("", rblf.notdir("/"))
assert_eq("", rblf.notdir(""))

assert_eq(
    ["build/make/tests/board.rbc", "build/make/tests/board_input_vars.rbc"],
    rblf.expand_wildcard("build/make/tests/board*.rbc")
)
assert_eq(
    ["build/make/tests/run.rbc", "build/make/tests/product.rbc"],
    rblf.expand_wildcard("build/make/tests/run.rbc build/make/tests/product.rbc")
)
assert_eq(
    ["build/make/tests/run.rbc"],
    rblf.expand_wildcard("build/make/tests/run.rbc build/make/tests/nonexistent.rbc")
)

(globals, config, globals_base) = rblf.product_configuration("test/device", init, input_variables_init)
assert_eq(
    {
      "PRODUCT_COPY_FILES": [
          "part_from:part_to",
          "device_from:device_to",
          "device/google/redfin/audio/audio_platform_info_noextcodec_snd.xml:||VENDOR-PATH-PH||/etc/audio/audio_platform_info_noextcodec_snd.xml",
          "xyz:/etc/xyz",
          "x.xml:/etc/x.xml",
          "y.xml:/etc/y.xml",
          "from/sub/x:to/x",
          "from/sub/y:to/y",
      ],
      "PRODUCT_HOST_PACKAGES": ["host"],
      "PRODUCT_PACKAGES": [
          "dev",
          "inc",
          "dev_after",
          "board1_in",
          "board1_is",
      ],
      "PRODUCT_PRODUCT_PROPERTIES": ["part_properties"]
    },
    { k:v for k, v in sorted(config.items()) }
)

ns = globals["$SOONG_CONFIG_NAMESPACES"]
assert_eq(
    {
        "NS1": {
            "v1": "abc abc_part1",
            "v2": "def"
        },
        "NS2": {
            "v3": "xyz"
        }
    },
    {k:v for k, v in sorted(ns.items()) }
)

assert_eq("Tiramisu", globals["PLATFORM_VERSION"])
assert_eq("31", globals["PLATFORM_SDK_VERSION"])

assert_eq("xyz", rblf.soong_config_get(globals, "NS2", "v3"))
assert_eq(None, rblf.soong_config_get(globals, "NS2", "nonexistant_var"))

goals = globals["$dist_for_goals"]
assert_eq(
    {
        "goal": [("dir1/file1", "out1"), ("dir1/file2", "out2"), ("dir2/file2", "file2")]
    },
    { k:v for k,v in sorted(goals.items()) }
)

(board_globals, board_config, board_globals_base) = rblf.board_configuration(board_init, board_input_vars_init)
assert_eq({"A_LIST_VARIABLE": ["foo", "bar"]}, board_globals)
assert_eq({"A_LIST_VARIABLE": ["foo"]}, board_globals_base)
