#!/usr/bin/env python3
# Copyright 2020 The Pigweed 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
#
#     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.
"""Tests for the Python runner."""

import os
from pathlib import Path
import platform
import tempfile
import unittest

from pw_build.python_runner import ExpressionError, GnPaths, Label, TargetInfo
from pw_build.python_runner import expand_expressions

ROOT = Path(r'C:\gn_root' if platform.system() == 'Windows' else '/gn_root')

TEST_PATHS = GnPaths(
    ROOT,
    ROOT / 'out',
    ROOT / 'some' / 'cwd',
    '//toolchains/cool:ToolChain',
)


class LabelTest(unittest.TestCase):
    """Tests GN label parsing."""
    def setUp(self):
        self._paths_and_toolchain_name = [
            (TEST_PATHS, 'ToolChain'),
            (GnPaths(*TEST_PATHS[:3], ''), ''),
        ]

    def test_root(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, '//')
            self.assertEqual(label.name, '')
            self.assertEqual(label.dir, ROOT)
            self.assertEqual(label.out_dir,
                             ROOT.joinpath('out', toolchain, 'obj'))
            self.assertEqual(label.gen_dir,
                             ROOT.joinpath('out', toolchain, 'gen'))

    def test_absolute(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, '//foo/bar:baz')
            self.assertEqual(label.name, 'baz')
            self.assertEqual(label.dir, ROOT.joinpath('foo/bar'))
            self.assertEqual(label.out_dir,
                             ROOT.joinpath('out', toolchain, 'obj/foo/bar'))
            self.assertEqual(label.gen_dir,
                             ROOT.joinpath('out', toolchain, 'gen/foo/bar'))

    def test_absolute_implicit_target(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, '//foo/bar')
            self.assertEqual(label.name, 'bar')
            self.assertEqual(label.dir, ROOT.joinpath('foo/bar'))
            self.assertEqual(label.out_dir,
                             ROOT.joinpath('out', toolchain, 'obj/foo/bar'))
            self.assertEqual(label.gen_dir,
                             ROOT.joinpath('out', toolchain, 'gen/foo/bar'))

    def test_relative(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, ':tgt')
            self.assertEqual(label.name, 'tgt')
            self.assertEqual(label.dir, ROOT.joinpath('some/cwd'))
            self.assertEqual(label.out_dir,
                             ROOT.joinpath('out', toolchain, 'obj/some/cwd'))
            self.assertEqual(label.gen_dir,
                             ROOT.joinpath('out', toolchain, 'gen/some/cwd'))

    def test_relative_subdir(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, 'tgt')
            self.assertEqual(label.name, 'tgt')
            self.assertEqual(label.dir, ROOT.joinpath('some/cwd/tgt'))
            self.assertEqual(
                label.out_dir,
                ROOT.joinpath('out', toolchain, 'obj/some/cwd/tgt'))
            self.assertEqual(
                label.gen_dir,
                ROOT.joinpath('out', toolchain, 'gen/some/cwd/tgt'))

    def test_relative_parent_dir(self):
        for paths, toolchain in self._paths_and_toolchain_name:
            label = Label(paths, '..:tgt')
            self.assertEqual(label.name, 'tgt')
            self.assertEqual(label.dir, ROOT.joinpath('some'))
            self.assertEqual(label.out_dir,
                             ROOT.joinpath('out', toolchain, 'obj/some'))
            self.assertEqual(label.gen_dir,
                             ROOT.joinpath('out', toolchain, 'gen/some'))


class ResolvePathTest(unittest.TestCase):
    """Tests GN path resolution."""
    def test_resolve_absolute(self):
        self.assertEqual(TEST_PATHS.resolve('//'), TEST_PATHS.root)
        self.assertEqual(TEST_PATHS.resolve('//foo/bar'),
                         TEST_PATHS.root / 'foo' / 'bar')
        self.assertEqual(TEST_PATHS.resolve('//foo/../baz'),
                         TEST_PATHS.root / 'baz')

    def test_resolve_relative(self):
        self.assertEqual(TEST_PATHS.resolve(''), TEST_PATHS.cwd)
        self.assertEqual(TEST_PATHS.resolve('foo'), TEST_PATHS.cwd / 'foo')
        self.assertEqual(TEST_PATHS.resolve('..'), TEST_PATHS.root / 'some')


NINJA_EXECUTABLE = '''\
defines =
framework_dirs =
include_dirs = -I../fake_module/public
cflags = -g3 -Og -fdiagnostics-color -g -fno-common -Wall -Wextra -Werror
cflags_c =
cflags_cc = -fno-rtti -Wnon-virtual-dtor -std=c++17 -Wno-register
target_output_name = this_is_a_test

build fake_toolchain/obj/fake_module/fake_test.fake_test.cc.o: fake_toolchain_cxx ../fake_module/fake_test.cc
build fake_toolchain/obj/fake_module/fake_test.fake_test_c.c.o: fake_toolchain_cc ../fake_module/fake_test_c.c

build fake_toolchain/obj/fake_module/test/fake_test.elf: fake_toolchain_link fake_toolchain/obj/fake_module/fake_test.fake_test.cc.o fake_toolchain/obj/fake_module/fake_test.fake_test_c.c.o
  ldflags = -Og -fdiagnostics-color
  libs =
  frameworks =
  output_extension =
  output_dir = host_clang_debug/obj/fake_module/test
'''

_SOURCE_SET_TEMPLATE = '''\
defines =
framework_dirs =
include_dirs = -I../fake_module/public
cflags = -g3 -Og -fdiagnostics-color -g -fno-common -Wall -Wextra -Werror
cflags_c =
cflags_cc = -fno-rtti -Wnon-virtual-dtor -std=c++17 -Wno-register
target_output_name = this_is_a_test

build fake_toolchain/obj/fake_module/fake_source_set.file_a.cc.o: fake_toolchain_cxx ../fake_module/file_a.cc
build fake_toolchain/obj/fake_module/fake_source_set.file_b.c.o: fake_toolchain_cc ../fake_module/file_b.c

build {path} fake_toolchain/obj/fake_module/fake_source_set.file_a.cc.o fake_toolchain/obj/fake_module/fake_source_set.file_b.c.o
  ldflags = -Og -fdiagnostics-color -Wno-error=deprecated
  libs =
  frameworks =
  output_extension =
  output_dir = host_clang_debug/obj/fake_module
'''

# GN originally used empty .stamp files to mark the completion of a group of
# dependencies. GN switched to using 'phony' Ninja targets instead, which don't
# require creating a new file.
_PHONY_BUILD_PATH = 'fake_toolchain/phony/fake_module/fake_source_set: phony'
_STAMP_BUILD_PATH = 'fake_toolchain/obj/fake_module/fake_source_set.stamp:'

NINJA_SOURCE_SET = _SOURCE_SET_TEMPLATE.format(path=_PHONY_BUILD_PATH)
NINJA_SOURCE_SET_STAMP = _SOURCE_SET_TEMPLATE.format(path=_STAMP_BUILD_PATH)


def _create_ninja_files(source_set: str) -> tuple:
    tempdir = tempfile.TemporaryDirectory(prefix='pw_build_test_')

    module = Path(tempdir.name, 'out', 'fake_toolchain', 'obj', 'fake_module')
    os.makedirs(module)
    module.joinpath('fake_test.ninja').write_text(NINJA_EXECUTABLE)
    module.joinpath('fake_source_set.ninja').write_text(source_set)
    module.joinpath('fake_no_objects.ninja').write_text('\n')

    outdir = Path(tempdir.name, 'out', 'fake_toolchain', 'obj', 'fake_module')

    paths = GnPaths(root=Path(tempdir.name),
                    build=Path(tempdir.name, 'out'),
                    cwd=Path(tempdir.name, 'some', 'module'),
                    toolchain='//tools:fake_toolchain')

    return tempdir, outdir, paths


class TargetTest(unittest.TestCase):
    """Tests querying GN target information."""
    def setUp(self):
        self._tempdir, self._outdir, self._paths = _create_ninja_files(
            NINJA_SOURCE_SET)

    def tearDown(self):
        self._tempdir.cleanup()

    def test_source_set_artifact(self):
        target = TargetInfo(self._paths, '//fake_module:fake_source_set')
        self.assertTrue(target.generated)
        self.assertIsNone(target.artifact)

    def test_source_set_object_files(self):
        target = TargetInfo(self._paths, '//fake_module:fake_source_set')
        self.assertTrue(target.generated)
        self.assertEqual(
            set(target.object_files), {
                self._outdir / 'fake_source_set.file_a.cc.o',
                self._outdir / 'fake_source_set.file_b.c.o',
            })

    def test_executable_object_files(self):
        target = TargetInfo(self._paths, '//fake_module:fake_test')
        self.assertEqual(
            set(target.object_files), {
                self._outdir / 'fake_test.fake_test.cc.o',
                self._outdir / 'fake_test.fake_test_c.c.o',
            })

    def test_executable_artifact(self):
        target = TargetInfo(self._paths, '//fake_module:fake_test')
        self.assertEqual(target.artifact,
                         self._outdir / 'test' / 'fake_test.elf')

    def test_non_existent_target(self):
        target = TargetInfo(self._paths,
                            '//fake_module:definitely_not_a_real_target')
        self.assertFalse(target.generated)
        self.assertIsNone(target.artifact)

    def test_non_existent_toolchain(self):
        target = TargetInfo(
            self._paths, '//fake_module:fake_source_set(//not_a:toolchain)')
        self.assertFalse(target.generated)
        self.assertIsNone(target.artifact)


class StampTargetTest(TargetTest):
    """Test with old-style .stamp files instead of phony Ninja targets."""
    def setUp(self):
        self._tempdir, self._outdir, self._paths = _create_ninja_files(
            NINJA_SOURCE_SET_STAMP)


class ExpandExpressionsTest(unittest.TestCase):
    """Tests expansion of expressions like <TARGET_FILE(//foo)>."""
    def setUp(self):
        self._tempdir, self._outdir, self._paths = _create_ninja_files(
            NINJA_SOURCE_SET)

    def tearDown(self):
        self._tempdir.cleanup()

    def _path(self, *segments: str, create: bool = False) -> str:
        path = Path(self._outdir, *segments)
        if create:
            os.makedirs(path.parent)
            path.touch()
        else:
            assert not path.exists()
        return str(path)

    def test_empty(self):
        self.assertEqual(list(expand_expressions(self._paths, '')), [''])

    def test_no_expressions(self):
        self.assertEqual(list(expand_expressions(self._paths, 'foobar')),
                         ['foobar'])
        self.assertEqual(
            list(expand_expressions(self._paths, '<NOT_AN_EXPRESSION()>')),
            ['<NOT_AN_EXPRESSION()>'])

    def test_incomplete_expression(self):
        for incomplete_expression in [
                '<TARGET_FILE(',
                '<TARGET_FILE(//foo)',
                '<TARGET_FILE(//foo>',
                '<TARGET_FILE(//foo) >',
                '--arg=<TARGET_FILE_IF_EXISTS(//foo) Hello>',
        ]:
            with self.assertRaises(ExpressionError):
                expand_expressions(self._paths, incomplete_expression)

    def test_target_file(self):
        path = self._path('test', 'fake_test.elf')

        for expr, expected in [
            ('<TARGET_FILE(//fake_module:fake_test)>', path),
            ('--arg=<TARGET_FILE(//fake_module:fake_test)>', f'--arg={path}'),
            ('--argument=<TARGET_FILE(//fake_module:fake_test)>;'
             '<TARGET_FILE(//fake_module:fake_test)>',
             f'--argument={path};{path}'),
        ]:
            self.assertEqual(list(expand_expressions(self._paths, expr)),
                             [expected])

    def test_target_objects_no_target_file(self):
        with self.assertRaisesRegex(ExpressionError, 'no output file'):
            expand_expressions(self._paths,
                               '<TARGET_FILE(//fake_module:fake_source_set)>')

    def test_target_file_non_existent_target(self):
        with self.assertRaisesRegex(ExpressionError, 'generated'):
            expand_expressions(self._paths, '<TARGET_FILE(//not_real:abc123)>')

    def test_target_file_if_exists(self):
        path = self._path('test', 'fake_test.elf', create=True)

        for expr, expected in [
            ('<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>', path),
            ('--arg=<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>',
             f'--arg={path}'),
            ('--argument=<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>;'
             '<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>',
             f'--argument={path};{path}'),
        ]:
            self.assertEqual(list(expand_expressions(self._paths, expr)),
                             [expected])

    def test_target_file_if_exists_arg_omitted(self):
        for expr in [
                '<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>',
                '<TARGET_FILE_IF_EXISTS(//fake_module:fake_test(fake)>',
                '<TARGET_FILE_IF_EXISTS(//not_a_module:nothing)>',
                '--arg=<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>',
                '--argument=<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>;'
                '<TARGET_FILE_IF_EXISTS(//fake_module:fake_test)>',
        ]:
            self.assertEqual(list(expand_expressions(self._paths, expr)), [])

    def test_target_file_if_exists_error_if_never_has_artifact(self):
        for expr in [
                '<TARGET_FILE_IF_EXISTS(//fake_module:fake_source_set)>'
                'bar=<TARGET_FILE_IF_EXISTS(//fake_module:fake_source_set)>'
                '<TARGET_FILE_IF_EXISTS(//fake_module:fake_no_objects)>',
                '--foo=<TARGET_FILE_IF_EXISTS(//fake_module:fake_no_objects)>',
        ]:
            with self.assertRaises(ExpressionError):
                expand_expressions(self._paths, expr)

    def test_target_objects(self):
        self.assertEqual(
            set(
                expand_expressions(
                    self._paths,
                    '<TARGET_OBJECTS(//fake_module:fake_source_set)>')), {
                        self._path('fake_source_set.file_a.cc.o'),
                        self._path('fake_source_set.file_b.c.o')
                    })
        self.assertEqual(
            set(
                expand_expressions(
                    self._paths, '<TARGET_OBJECTS(//fake_module:fake_test)>')),
            {
                self._path('fake_test.fake_test.cc.o'),
                self._path('fake_test.fake_test_c.c.o')
            })

    def test_target_objects_no_objects(self):
        self.assertEqual(
            list(
                expand_expressions(
                    self._paths,
                    '<TARGET_OBJECTS(//fake_module:fake_no_objects)>')), [])

    def test_target_objects_other_content_in_arg(self):
        for arg in [
                '--foo=<TARGET_OBJECTS(//fake_module:fake_no_objects)>',
                '<TARGET_OBJECTS(//fake_module:fake_no_objects)>bar',
                '--foo<TARGET_OBJECTS(//fake_module:fake_no_objects)>bar',
                '<TARGET_OBJECTS(//fake_module:fake_no_objects)>'
                '<TARGET_OBJECTS(//fake_module:fake_no_objects)>',
                '<TARGET_OBJECTS(//fake_module:fake_source_set)>'
                '<TARGET_OBJECTS(//fake_module:fake_source_set)>',
        ]:
            with self.assertRaises(ExpressionError):
                expand_expressions(self._paths, arg)

    def test_target_objects_non_existent_target(self):
        with self.assertRaisesRegex(ExpressionError, 'generated'):
            expand_expressions(self._paths, '<TARGET_OBJECTS(//not_real)>')


class StampExpandExpressionsTest(TargetTest):
    """Test with old-style .stamp files instead of phony Ninja targets."""
    def setUp(self):
        self._tempdir, self._outdir, self._paths = _create_ninja_files(
            NINJA_SOURCE_SET_STAMP)


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