# 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 front_end import glue
from front_end import test_util
from public import ir_pb2
from util import error
from util import parser_types

_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()
