# Copyright 2015-2017 Google Inc. All Rights Reserved.
#
# 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
#
#     http://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.
"""Entry points for YAPF.

The main APIs that YAPF exposes to drive the reformatting.

  FormatFile(): reformat a file.
  FormatCode(): reformat a string of code.

These APIs have some common arguments:

  style_config: (string) Either a style name or a path to a file that contains
    formatting style settings. If None is specified, use the default style
    as set in style.DEFAULT_STYLE_FACTORY
  lines: (list of tuples of integers) A list of tuples of lines, [start, end],
    that we want to format. The lines are 1-based indexed. It can be used by
    third-party code (e.g., IDEs) when reformatting a snippet of code rather
    than a whole file.
  print_diff: (bool) Instead of returning the reformatted source, return a
    diff that turns the formatted source into reformatter source.
  verify: (bool) True if reformatted code should be verified for syntax.
"""

import difflib
import re
import sys

from lib2to3.pgen2 import tokenize

from yapf.yapflib import blank_line_calculator
from yapf.yapflib import comment_splicer
from yapf.yapflib import continuation_splicer
from yapf.yapflib import file_resources
from yapf.yapflib import py3compat
from yapf.yapflib import pytree_unwrapper
from yapf.yapflib import pytree_utils
from yapf.yapflib import reformatter
from yapf.yapflib import split_penalty
from yapf.yapflib import style
from yapf.yapflib import subtype_assigner


def FormatFile(filename,
               style_config=None,
               lines=None,
               print_diff=False,
               verify=False,
               in_place=False,
               logger=None):
  """Format a single Python file and return the formatted code.

  Arguments:
    filename: (unicode) The file to reformat.
    in_place: (bool) If True, write the reformatted code back to the file.
    logger: (io streamer) A stream to output logging.
    remaining arguments: see comment at the top of this module.

  Returns:
    Tuple of (reformatted_code, encoding, changed). reformatted_code is None if
    the file is sucessfully written to (having used in_place). reformatted_code
    is a diff if print_diff is True.

  Raises:
    IOError: raised if there was an error reading the file.
    ValueError: raised if in_place and print_diff are both specified.
  """
  _CheckPythonVersion()

  if in_place and print_diff:
    raise ValueError('Cannot pass both in_place and print_diff.')

  original_source, newline, encoding = ReadFile(filename, logger)
  reformatted_source, changed = FormatCode(
      original_source,
      style_config=style_config,
      filename=filename,
      lines=lines,
      print_diff=print_diff,
      verify=verify)
  if reformatted_source.rstrip('\n'):
    lines = reformatted_source.rstrip('\n').split('\n')
    reformatted_source = newline.join(line for line in lines) + newline
  if in_place:
    if original_source and original_source != reformatted_source:
      file_resources.WriteReformattedCode(filename, reformatted_source,
                                          in_place, encoding)
    return None, encoding, changed

  return reformatted_source, encoding, changed


def FormatCode(unformatted_source,
               filename='<unknown>',
               style_config=None,
               lines=None,
               print_diff=False,
               verify=False):
  """Format a string of Python code.

  This provides an alternative entry point to YAPF.

  Arguments:
    unformatted_source: (unicode) The code to format.
    filename: (unicode) The name of the file being reformatted.
    remaining arguments: see comment at the top of this module.

  Returns:
    Tuple of (reformatted_source, changed). reformatted_source conforms to the
    desired formatting style. changed is True if the source changed.
  """
  _CheckPythonVersion()
  style.SetGlobalStyle(style.CreateStyleFromConfig(style_config))
  if not unformatted_source.endswith('\n'):
    unformatted_source += '\n'
  tree = pytree_utils.ParseCodeToTree(unformatted_source)

  # Run passes on the tree, modifying it in place.
  comment_splicer.SpliceComments(tree)
  continuation_splicer.SpliceContinuations(tree)
  subtype_assigner.AssignSubtypes(tree)
  split_penalty.ComputeSplitPenalties(tree)
  blank_line_calculator.CalculateBlankLines(tree)

  uwlines = pytree_unwrapper.UnwrapPyTree(tree)
  for uwl in uwlines:
    uwl.CalculateFormattingInformation()

  _MarkLinesToFormat(uwlines, lines)
  reformatted_source = reformatter.Reformat(uwlines, verify)

  if unformatted_source == reformatted_source:
    return '' if print_diff else reformatted_source, False

  code_diff = _GetUnifiedDiff(
      unformatted_source, reformatted_source, filename=filename)

  if print_diff:
    return code_diff, code_diff != ''

  return reformatted_source, True


def _CheckPythonVersion():  # pragma: no cover
  errmsg = 'yapf is only supported for Python 2.7 or 3.4+'
  if sys.version_info[0] == 2:
    if sys.version_info[1] < 7:
      raise RuntimeError(errmsg)
  elif sys.version_info[0] == 3:
    if sys.version_info[1] < 4:
      raise RuntimeError(errmsg)


def ReadFile(filename, logger=None):
  """Read the contents of the file.

  An optional logger can be specified to emit messages to your favorite logging
  stream. If specified, then no exception is raised. This is external so that it
  can be used by third-party applications.

  Arguments:
    filename: (unicode) The name of the file.
    logger: (function) A function or lambda that takes a string and emits it.

  Returns:
    The contents of filename.

  Raises:
    IOError: raised if there was an error reading the file.
  """
  try:
    with open(filename, 'rb') as fd:
      encoding = tokenize.detect_encoding(fd.readline)[0]
  except IOError as err:
    if logger:
      logger(err)
    raise

  try:
    # Preserves line endings.
    with py3compat.open_with_encoding(
        filename, mode='r', encoding=encoding, newline='') as fd:
      lines = fd.readlines()

    line_ending = file_resources.LineEnding(lines)
    source = '\n'.join(line.rstrip('\r\n') for line in lines) + '\n'
    return source, line_ending, encoding
  except IOError as err:  # pragma: no cover
    if logger:
      logger(err)
    raise


DISABLE_PATTERN = r'^#.*\byapf:\s*disable\b'
ENABLE_PATTERN = r'^#.*\byapf:\s*enable\b'


def _MarkLinesToFormat(uwlines, lines):
  """Skip sections of code that we shouldn't reformat."""
  if lines:
    for uwline in uwlines:
      uwline.disable = True

    # Sort and combine overlapping ranges.
    lines = sorted(lines)
    line_ranges = [lines[0]] if len(lines[0]) else []
    index = 1
    while index < len(lines):
      current = line_ranges[-1]
      if lines[index][0] <= current[1]:
        # The ranges overlap, so combine them.
        line_ranges[-1] = (current[0], max(lines[index][1], current[1]))
      else:
        line_ranges.append(lines[index])
      index += 1

    # Mark lines to format as not being disabled.
    index = 0
    for start, end in sorted(line_ranges):
      while index < len(uwlines) and uwlines[index].last.lineno < start:
        index += 1
      if index >= len(uwlines):
        break

      while index < len(uwlines):
        if uwlines[index].lineno > end:
          break
        if (uwlines[index].lineno >= start or
            uwlines[index].last.lineno >= start):
          uwlines[index].disable = False
        index += 1

  # Now go through the lines and disable any lines explicitly marked as
  # disabled.
  index = 0
  while index < len(uwlines):
    uwline = uwlines[index]
    if uwline.is_comment:
      if _DisableYAPF(uwline.first.value.strip()):
        index += 1
        while index < len(uwlines):
          uwline = uwlines[index]
          if uwline.is_comment and _EnableYAPF(uwline.first.value.strip()):
            break
          uwline.disable = True
          index += 1
    elif re.search(DISABLE_PATTERN, uwline.last.value.strip(), re.IGNORECASE):
      uwline.disable = True
    index += 1


def _DisableYAPF(line):
  return (
      re.search(DISABLE_PATTERN, line.split('\n')[0].strip(), re.IGNORECASE) or
      re.search(DISABLE_PATTERN, line.split('\n')[-1].strip(), re.IGNORECASE))


def _EnableYAPF(line):
  return (
      re.search(ENABLE_PATTERN, line.split('\n')[0].strip(), re.IGNORECASE) or
      re.search(ENABLE_PATTERN, line.split('\n')[-1].strip(), re.IGNORECASE))


def _GetUnifiedDiff(before, after, filename='code'):
  """Get a unified diff of the changes.

  Arguments:
    before: (unicode) The original source code.
    after: (unicode) The reformatted source code.
    filename: (unicode) The code's filename.

  Returns:
    The unified diff text.
  """
  before = before.splitlines()
  after = after.splitlines()
  return '\n'.join(
      difflib.unified_diff(
          before,
          after,
          filename,
          filename,
          '(original)',
          '(reformatted)',
          lineterm='')) + '\n'
