#!/usr/bin/env python3

# Copyright (c) 2021 Project CHIP Authors
#
# 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.

import difflib
import os
import subprocess
import sys
import unittest
from typing import List

SCRIPT_ROOT = os.path.dirname(__file__)


def build_expected_output(source: str, root: str, out: str) -> List[str]:
    with open(os.path.join(SCRIPT_ROOT, source), 'rt') as f:
        for l in f.readlines():
            yield l.replace("{root}", root).replace("{out}", out)


def build_actual_output(root: str, out: str, args: List[str]) -> List[str]:
    # Fake out that we have a project root
    binary = os.path.join(SCRIPT_ROOT, 'build_examples.py')

    runenv = {}
    runenv.update(os.environ)
    runenv.update({
        'PW_PROJECT_ROOT': root,
        'ANDROID_NDK_HOME': 'TEST_ANDROID_NDK_HOME',
        'ANDROID_HOME': 'TEST_ANDROID_HOME',
        'TIZEN_SDK_ROOT': 'TEST_TIZEN_SDK_ROOT',
        'TIZEN_SDK_SYSROOT': 'TEST_TIZEN_SDK_SYSROOT',
        'TELINK_ZEPHYR_SDK_DIR': 'TELINK_ZEPHYR_SDK_DIR',
        'SYSROOT_AARCH64': 'SYSROOT_AARCH64',
        'NXP_K32W0_SDK_ROOT': 'TEST_NXP_K32W0_SDK_ROOT',
        'IMX_SDK_ROOT': 'IMX_SDK_ROOT',
        'TI_SYSCONFIG_ROOT': 'TEST_TI_SYSCONFIG_ROOT',
    })

    retval = subprocess.run([
        binary,
        '--log-level', 'FATAL',
        '--dry-run',
        '--repo', root,
        '--out-prefix', out,
    ] + args, stdout=subprocess.PIPE, check=True, encoding='UTF-8', env=runenv)

    result = [l + '\n' for l in retval.stdout.split('\n')]

    # ensure a single terminating newline: easier to edit since autoformat
    # often strips ending double newlines on text files
    while result[-1] == '\n':
        result = result[:-1]

    return result


class TestBuilder(unittest.TestCase):

    def assertCommandOutput(self, expected_file: str, args: List[str]):
        ROOT = '/TEST/BUILD/ROOT'
        OUT = '/OUTPUT/DIR'

        expected = [l for l in build_expected_output(expected_file, ROOT, OUT)]
        actual = [l for l in build_actual_output(ROOT, OUT, args)]

        diffs = [line for line in difflib.unified_diff(expected, actual)]

        if diffs:
            reference = os.path.basename(expected_file) + '.actual'
            with open(reference, 'wt') as fo:
                for l in build_actual_output(ROOT, OUT, args):
                    fo.write(l.replace(ROOT, '{root}').replace(OUT, '{out}'))

            msg = "DIFFERENCE between expected and generated output in %s\n" % expected_file
            msg += "Expected file can be found in %s" % reference
            for l in diffs:
                msg += ("\n   " + l.replace(ROOT,
                                            '{root}').replace(OUT, '{out}').strip())
            self.fail(msg)

    @unittest.skipUnless(sys.platform == 'linux', 'Build on linux test')
    @unittest.skipUnless(os.uname().machine == 'x86_64', 'Validation x64 and crosscompile, requires linux x64')
    def test_linux64_targets(self):
        self.assertCommandOutput(
            os.path.join('testdata', 'all_targets_linux_x64.txt'),
            'targets'.split(' ')
        )

    def test_general_dry_runs(self):
        # A sampling of targets and variants to validate that
        # build options do not change too much
        TARGETS = [
            'esp32-devkitc-light-rpc',
            'esp32-m5stack-all-clusters-minimal-rpc-ipv6only',
            'android-arm64-chip-tool',
            'nrf-nrf52840dk-pump',
            'efr32-brd4161a-light-rpc'
        ]

        for target in TARGETS:
            expected = os.path.join('testdata', f'dry_run_{target}.txt')
            self.assertCommandOutput(expected, f'--target {target} --dry-run build'.split(' '))

    @unittest.skipUnless(sys.platform == 'linux', 'Build on linux test')
    @unittest.skipUnless(os.uname().machine == 'x86_64', 'Validation x64 and crosscompile, requires linux x64')
    def test_linux_dry_runs(self):
        TARGETS = [
            'linux-arm64-chip-tool-ipv6only-clang',
            'linux-arm64-ota-requestor-nodeps-ipv6only',
            'linux-x64-all-clusters-coverage',
        ]

        for target in TARGETS:
            expected = os.path.join('testdata', f'dry_run_{target}.txt')
            self.assertCommandOutput(expected, f'--target {target} --dry-run build'.split(' '))


if __name__ == '__main__':
    unittest.main()
