#!/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 tempfile
import unittest

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

TEST_PATHS = GnPaths(Path('/gn_root'), Path('/gn_root/out'),
                     Path('/gn_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, Path('/gn_root'))
            self.assertEqual(label.out_dir,
                             Path('/gn_root/out', toolchain, 'obj'))
            self.assertEqual(label.gen_dir,
                             Path('/gn_root/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, Path('/gn_root/foo/bar'))
            self.assertEqual(label.out_dir,
                             Path('/gn_root/out', toolchain, 'obj/foo/bar'))
            self.assertEqual(label.gen_dir,
                             Path('/gn_root/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, Path('/gn_root/foo/bar'))
            self.assertEqual(label.out_dir,
                             Path('/gn_root/out', toolchain, 'obj/foo/bar'))
            self.assertEqual(label.gen_dir,
                             Path('/gn_root/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, Path('/gn_root/some/cwd'))
            self.assertEqual(label.out_dir,
                             Path('/gn_root/out', toolchain, 'obj/some/cwd'))
            self.assertEqual(label.gen_dir,
                             Path('/gn_root/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, Path('/gn_root/some/cwd/tgt'))
            self.assertEqual(
                label.out_dir,
                Path('/gn_root/out', toolchain, 'obj/some/cwd/tgt'))
            self.assertEqual(
                label.gen_dir,
                Path('/gn_root/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, Path('/gn_root/some'))
            self.assertEqual(label.out_dir,
                             Path('/gn_root/out', toolchain, 'obj/some'))
            self.assertEqual(label.gen_dir,
                             Path('/gn_root/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_tolchain_link fake_tolchain/obj/fake_module/fake_test.fake_test.cc.o fake_tolchain/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
'''

NINJA_SOURCE_SET = '''\
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 fake_toolchain/obj/fake_module/fake_source_set.stamp: fake_tolchain_link fake_tolchain/obj/fake_module/fake_source_set.file_a.cc.o fake_tolchain/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
'''


def _create_ninja_files():
    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(NINJA_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()

    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 ExpandExpressionsTest(unittest.TestCase):
    """Tests expansion of expressions like <TARGET_FILE(//foo)>."""
    def setUp(self):
        self._tempdir, self._outdir, self._paths = _create_ninja_files()

    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)>')


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