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

"""Emboss front end.

This is an internal tool, normally called by the "embossc" driver, rather than
directly by a user.  It parses a .emb file and its dependencies, and prints an
intermediate representation of the parse trees and symbol tables to stdout, or
prints various bits of debug info, depending on which flags are passed.
"""

from __future__ import print_function

import argparse
import os
from os import path
import sys

from compiler.front_end import glue
from compiler.front_end import module_ir
from compiler.util import error


def _parse_command_line(argv):
  """Parses the given command-line arguments."""
  parser = argparse.ArgumentParser(description="Emboss compiler front end.",
                                   prog=argv[0])
  parser.add_argument("input_file",
                      type=str,
                      nargs=1,
                      help=".emb file to compile.")
  parser.add_argument("--debug-show-tokenization",
                      action="store_true",
                      help="Show the tokenization of the main input file.")
  parser.add_argument("--debug-show-parse-tree",
                      action="store_true",
                      help="Show the parse tree of the main input file.")
  parser.add_argument("--debug-show-module-ir",
                      action="store_true",
                      help="Show the module-level IR of the main input file "
                           "before symbol resolution.")
  parser.add_argument("--debug-show-full-ir",
                      action="store_true",
                      help="Show the final IR of the main input file.")
  parser.add_argument("--debug-show-used-productions",
                      action="store_true",
                      help="Show all of the grammar productions used in "
                           "parsing the main input file.")
  parser.add_argument("--debug-show-unused-productions",
                      action="store_true",
                      help="Show all of the grammar productions not used in "
                           "parsing the main input file.")
  parser.add_argument("--output-ir-to-stdout",
                      action="store_true",
                      help="Dump serialized IR to stdout.")
  parser.add_argument("--output-file",
                      type=str,
                      help="Write serialized IR to file.")
  parser.add_argument("--no-debug-show-header-lines",
                      dest="debug_show_header_lines",
                      action="store_false",
                      help="Print header lines before output if true.")
  parser.add_argument("--color-output",
                      default="if_tty",
                      choices=["always", "never", "if_tty", "auto"],
                      help="Print error messages using color.  'auto' is a "
                           "synonym for 'if_tty'.")
  parser.add_argument("--import-dir", "-I",
                      dest="import_dirs",
                      action="append",
                      default=["."],
                      help="A directory to use when searching for imported "
                           "embs.  If no import_dirs are specified, the "
                           "current directory will be used.")
  return parser.parse_args(argv[1:])


def _show_errors(errors, ir, flags):
  """Prints errors with source code snippets."""
  source_codes = {}
  if ir:
    for module in ir.module:
      source_codes[module.source_file_name] = module.source_text
  use_color = (flags.color_output == "always" or
               (flags.color_output in ("auto", "if_tty") and
                os.isatty(sys.stderr.fileno())))
  print(error.format_errors(errors, source_codes, use_color), file=sys.stderr)


def _find_in_dirs_and_read(import_dirs):
  """Returns a function which will search import_dirs for a file."""

  def _find_and_read(file_name):
    """Searches import_dirs for file_name and returns the contents."""
    errors = []
    # *All* source files, including the one specified on the command line, will
    # be searched for in the import_dirs.  This may be surprising, especially if
    # the current directory is *not* an import_dir.
    # TODO(bolms): Determine if this is really the desired behavior.
    for import_dir in import_dirs:
      full_name = path.join(import_dir, file_name)
      try:
        with open(full_name) as f:
          # As written, this follows the typical compiler convention of checking
          # the include/import directories in the order specified by the user,
          # and always reading the first matching file, even if other files
          # might match in later directories.  This lets files shadow other
          # files, which can be useful in some cases (to override things), but
          # can also cause accidental shadowing, which can be tricky to fix.
          #
          # TODO(bolms): Check if any other files with the same name are in the
          # import path, and give a warning or error?
          return f.read(), None
      except IOError as e:
        errors.append(str(e))
    return None, errors + ["import path " + ":".join(import_dirs)]

  return _find_and_read


def main(flags):
  ir, debug_info, errors = glue.parse_emboss_file(
      flags.input_file[0], _find_in_dirs_and_read(flags.import_dirs))
  if errors:
    _show_errors(errors, ir, flags)
    return 1
  main_module_debug_info = debug_info.modules[flags.input_file[0]]
  if flags.debug_show_tokenization:
    if flags.debug_show_header_lines:
      print("Tokenization:")
    print(main_module_debug_info.format_tokenization())
  if flags.debug_show_parse_tree:
    if flags.debug_show_header_lines:
      print("Parse Tree:")
    print(main_module_debug_info.format_parse_tree())
  if flags.debug_show_module_ir:
    if flags.debug_show_header_lines:
      print("Module IR:")
    print(main_module_debug_info.format_module_ir())
  if flags.debug_show_full_ir:
    if flags.debug_show_header_lines:
      print("Full IR:")
    print(str(ir))
  if flags.debug_show_used_productions:
    if flags.debug_show_header_lines:
      print("Used Productions:")
    print(glue.format_production_set(main_module_debug_info.used_productions))
  if flags.debug_show_unused_productions:
    if flags.debug_show_header_lines:
      print("Unused Productions:")
    print(glue.format_production_set(
        set(module_ir.PRODUCTIONS) - main_module_debug_info.used_productions))
  if flags.output_ir_to_stdout:
    print(ir.to_json())
  if flags.output_file:
    with open(flags.output_file, "w") as f:
      f.write(ir.to_json())
  return 0


if __name__ == "__main__":
  sys.exit(main(_parse_command_line(sys.argv)))
