# Copyright 2019 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.

"""Tests for glue."""

import pkgutil
import unittest

from compiler.front_end import glue
from compiler.util import error
from compiler.util import ir_pb2
from compiler.util import parser_types
from compiler.util import test_util

_location = parser_types.make_location

_ROOT_PACKAGE = "testdata.golden"
_GOLDEN_PATH = ""

_SPAN_SE_LOG_FILE_PATH = _GOLDEN_PATH + "span_se_log_file_status.emb"
_SPAN_SE_LOG_FILE_EMB = pkgutil.get_data(
    _ROOT_PACKAGE, _SPAN_SE_LOG_FILE_PATH).decode(encoding="UTF-8")
_SPAN_SE_LOG_FILE_READER = test_util.dict_file_reader(
    {_SPAN_SE_LOG_FILE_PATH: _SPAN_SE_LOG_FILE_EMB})
_SPAN_SE_LOG_FILE_IR = ir_pb2.Module.from_json(
    pkgutil.get_data(
        _ROOT_PACKAGE,
        _GOLDEN_PATH + "span_se_log_file_status.ir.txt"
    ).decode(encoding="UTF-8"))
_SPAN_SE_LOG_FILE_PARSE_TREE_TEXT = pkgutil.get_data(
    _ROOT_PACKAGE,
    _GOLDEN_PATH + "span_se_log_file_status.parse_tree.txt"
).decode(encoding="UTF-8")
_SPAN_SE_LOG_FILE_TOKENIZATION_TEXT = pkgutil.get_data(
    _ROOT_PACKAGE,
    _GOLDEN_PATH + "span_se_log_file_status.tokens.txt"
).decode(encoding="UTF-8")


class FrontEndGlueTest(unittest.TestCase):
  """Tests for front_end.glue."""

  def test_parse_module(self):
    # parse_module(file) should return the same thing as
    # parse_module_text(text), assuming file can be read.
    main_module, debug_info, errors = glue.parse_module(
        _SPAN_SE_LOG_FILE_PATH, _SPAN_SE_LOG_FILE_READER)
    main_module2, debug_info2, errors2 = glue.parse_module_text(
        _SPAN_SE_LOG_FILE_EMB, _SPAN_SE_LOG_FILE_PATH)
    self.assertEqual([], errors)
    self.assertEqual([], errors2)
    self.assertEqual(main_module, main_module2)
    self.assertEqual(debug_info, debug_info2)

  def test_parse_module_no_such_file(self):
    file_name = "nonexistent.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader({}))
    self.assertEqual([[
        error.error("nonexistent.emb", _location((1, 1), (1, 1)),
                    "Unable to read file."),
        error.note("nonexistent.emb", _location((1, 1), (1, 1)),
                   "File 'nonexistent.emb' not found."),
    ]], errors)
    self.assertFalse(file_name in debug_info.modules)
    self.assertFalse(ir)

  def test_parse_module_tokenization_error(self):
    file_name = "tokens.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader({file_name: "@"}))
    self.assertTrue(debug_info.modules[file_name].source_code)
    self.assertTrue(errors)
    self.assertEqual("Unrecognized token", errors[0][0].message)
    self.assertFalse(ir)

  def test_parse_module_indentation_error(self):
    file_name = "indent.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader(
            {file_name: "struct Foo:\n"
                        "  1 [+1] Int x\n"
                        " 2 [+1] Int y\n"}))
    self.assertTrue(debug_info.modules[file_name].source_code)
    self.assertTrue(errors)
    self.assertEqual("Bad indentation", errors[0][0].message)
    self.assertFalse(ir)

  def test_parse_module_parse_error(self):
    file_name = "parse.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader(
            {file_name: "struct foo:\n"
                        "  1 [+1] Int x\n"
                        "  3 [+1] Int y\n"}))
    self.assertTrue(debug_info.modules[file_name].source_code)
    self.assertEqual([[
        error.error(file_name, _location((1, 8), (1, 11)),
                    "A type name must be CamelCase.\n"
                    "Found 'foo' (SnakeWord), expected CamelWord.")
    ]], errors)
    self.assertFalse(ir)

  def test_parse_error(self):
    file_name = "parse.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader(
            {file_name: "struct foo:\n"
                        "  1 [+1]  Int  x\n"
                        "  2 [+1]  Int  y\n"}))
    self.assertTrue(debug_info.modules[file_name].source_code)
    self.assertEqual([[
        error.error(file_name, _location((1, 8), (1, 11)),
                    "A type name must be CamelCase.\n"
                    "Found 'foo' (SnakeWord), expected CamelWord.")
    ]], errors)
    self.assertFalse(ir)

  def test_circular_dependency_error(self):
    file_name = "cycle.emb"
    ir, debug_info, errors = glue.parse_emboss_file(
        file_name, test_util.dict_file_reader({
            file_name: "struct Foo:\n"
                       "  0 [+field1]  UInt  field1\n"
        }))
    self.assertTrue(debug_info.modules[file_name].source_code)
    self.assertTrue(errors)
    self.assertEqual("Dependency cycle\nfield1", errors[0][0].message)
    self.assertFalse(ir)

  def test_ir_from_parse_module(self):
    log_file_path_ir = ir_pb2.Module()
    log_file_path_ir.CopyFrom(_SPAN_SE_LOG_FILE_IR)
    log_file_path_ir.source_file_name = _SPAN_SE_LOG_FILE_PATH
    self.assertEqual(log_file_path_ir, glue.parse_module(
        _SPAN_SE_LOG_FILE_PATH, _SPAN_SE_LOG_FILE_READER).ir)

  def test_debug_info_from_parse_module(self):
    debug_info = glue.parse_module(_SPAN_SE_LOG_FILE_PATH,
                                   _SPAN_SE_LOG_FILE_READER).debug_info
    self.maxDiff = 200000  # pylint:disable=invalid-name
    self.assertEqual(_SPAN_SE_LOG_FILE_TOKENIZATION_TEXT.strip(),
                     debug_info.format_tokenization().strip())
    self.assertEqual(_SPAN_SE_LOG_FILE_PARSE_TREE_TEXT.strip(),
                     debug_info.format_parse_tree().strip())
    self.assertEqual(_SPAN_SE_LOG_FILE_IR, debug_info.ir)
    self.assertEqual(_SPAN_SE_LOG_FILE_IR.to_json(indent=2),
                     debug_info.format_module_ir())

  def test_parse_emboss_file(self):
    # parse_emboss_file calls parse_module, wraps its results, and calls
    # symbol_resolver.resolve_symbols() on the resulting IR.
    ir, debug_info, errors = glue.parse_emboss_file(_SPAN_SE_LOG_FILE_PATH,
                                                    _SPAN_SE_LOG_FILE_READER)
    module_ir, module_debug_info, module_errors = glue.parse_module(
        _SPAN_SE_LOG_FILE_PATH, _SPAN_SE_LOG_FILE_READER)
    self.assertEqual([], errors)
    self.assertEqual([], module_errors)
    self.assertTrue(test_util.proto_is_superset(ir.module[0], module_ir))
    self.assertEqual(module_debug_info,
                     debug_info.modules[_SPAN_SE_LOG_FILE_PATH])
    self.assertEqual(2, len(debug_info.modules))
    self.assertEqual(2, len(ir.module))
    self.assertEqual(_SPAN_SE_LOG_FILE_PATH, ir.module[0].source_file_name)
    self.assertEqual("", ir.module[1].source_file_name)

  def test_synthetic_error(self):
    file_name = "missing_byte_order_attribute.emb"
    ir, unused_debug_info, errors = glue.only_parse_emboss_file(
        file_name, test_util.dict_file_reader({
            file_name: "struct Foo:\n"
                       "  0 [+8]  UInt  field\n"
        }))
    self.assertFalse(errors)
    # Artificially mark the first field as is_synthetic.
    first_field = ir.module[0].type[0].structure.field[0]
    first_field.source_location.is_synthetic = True
    ir, errors = glue.process_ir(ir, None)
    self.assertTrue(errors)
    self.assertEqual("Attribute 'byte_order' required on field which is byte "
                     "order dependent.", errors[0][0].message)
    self.assertTrue(errors[0][0].location.is_synthetic)
    self.assertFalse(ir)

  def test_suppressed_synthetic_error(self):
    file_name = "triplicate_symbol.emb"
    ir, unused_debug_info, errors = glue.only_parse_emboss_file(
        file_name, test_util.dict_file_reader({
            file_name: "struct Foo:\n"
                       "  0 [+1]  UInt  field\n"
                       "  1 [+1]  UInt  field\n"
                       "  2 [+1]  UInt  field\n"
        }))
    self.assertFalse(errors)
    # Artificially mark the name of the second field as is_synthetic.
    second_field = ir.module[0].type[0].structure.field[1]
    second_field.name.source_location.is_synthetic = True
    second_field.name.name.source_location.is_synthetic = True
    ir, errors = glue.process_ir(ir, None)
    self.assertEqual(1, len(errors))
    self.assertEqual("Duplicate name 'field'", errors[0][0].message)
    self.assertFalse(errors[0][0].location.is_synthetic)
    self.assertFalse(errors[0][1].location.is_synthetic)
    self.assertFalse(ir)


class DebugInfoTest(unittest.TestCase):
  """Tests for DebugInfo and ModuleDebugInfo classes."""

  def test_debug_info_initialization(self):
    debug_info = glue.DebugInfo()
    self.assertEqual({}, debug_info.modules)

  def test_debug_info_invalid_attribute_set(self):
    debug_info = glue.DebugInfo()
    with self.assertRaises(AttributeError):
      debug_info.foo = "foo"

  def test_debug_info_equality(self):
    debug_info = glue.DebugInfo()
    debug_info2 = glue.DebugInfo()
    self.assertEqual(debug_info, debug_info2)
    debug_info.modules["foo"] = glue.ModuleDebugInfo("foo")
    self.assertNotEqual(debug_info, debug_info2)
    debug_info2.modules["foo"] = glue.ModuleDebugInfo("foo")
    self.assertEqual(debug_info, debug_info2)

  def test_module_debug_info_initialization(self):
    module_info = glue.ModuleDebugInfo("bar.emb")
    self.assertEqual("bar.emb", module_info.file_name)
    self.assertEqual(None, module_info.tokens)
    self.assertEqual(None, module_info.parse_tree)
    self.assertEqual(None, module_info.ir)
    self.assertEqual(None, module_info.used_productions)

  def test_module_debug_info_attribute_set(self):
    module_info = glue.ModuleDebugInfo("bar.emb")
    module_info.tokens = "a"
    module_info.parse_tree = "b"
    module_info.ir = "c"
    module_info.used_productions = "d"
    module_info.source_code = "e"
    self.assertEqual("a", module_info.tokens)
    self.assertEqual("b", module_info.parse_tree)
    self.assertEqual("c", module_info.ir)
    self.assertEqual("d", module_info.used_productions)
    self.assertEqual("e", module_info.source_code)

  def test_module_debug_info_bad_attribute_set(self):
    module_info = glue.ModuleDebugInfo("bar.emb")
    with self.assertRaises(AttributeError):
      module_info.foo = "foo"

  def test_module_debug_info_equality(self):
    module_info = glue.ModuleDebugInfo("foo")
    module_info2 = glue.ModuleDebugInfo("foo")
    module_info_bar = glue.ModuleDebugInfo("bar")
    self.assertEqual(module_info, module_info2)
    module_info_bar = glue.ModuleDebugInfo("bar")
    self.assertNotEqual(module_info, module_info_bar)
    module_info.tokens = []
    self.assertNotEqual(module_info, module_info2)
    module_info2.tokens = []
    self.assertEqual(module_info, module_info2)
    module_info.parse_tree = []
    self.assertNotEqual(module_info, module_info2)
    module_info2.parse_tree = []
    self.assertEqual(module_info, module_info2)
    module_info.ir = []
    self.assertNotEqual(module_info, module_info2)
    module_info2.ir = []
    self.assertEqual(module_info, module_info2)
    module_info.used_productions = []
    self.assertNotEqual(module_info, module_info2)
    module_info2.used_productions = []
    self.assertEqual(module_info, module_info2)


class TestFormatProductionSet(unittest.TestCase):
  """Tests for format_production_set."""

  def test_format_production_set(self):
    production_texts = ["A -> B", "B -> C", "A -> C", "C -> A"]
    productions = [parser_types.Production.parse(p) for p in production_texts]
    self.assertEqual("\n".join(sorted(production_texts)),
                     glue.format_production_set(set(productions)))


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