#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import difflib
import os
import re
import unittest

from strict_enum_value_checker import StrictEnumValueChecker

class MockLogging(object):
  def __init__(self):
    self.lines = []

  def info(self, message):
    self.lines.append(message)

  def debug(self, message):
    self.lines.append(message)

class MockInputApi(object):
  def __init__(self):
    self.re = re
    self.os_path = os.path
    self.files = []
    self.is_committing = False
    self.logging = MockLogging()

  def AffectedFiles(self, include_deletes=None):
    return self.files


class MockOutputApi(object):
  class PresubmitResult(object):
    def __init__(self, message, items=None, long_text=""):
      self.message = message
      self.items = items
      self.long_text = long_text

  class PresubmitError(PresubmitResult):
    def __init__(self, message, items, long_text=""):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = "error"

  class PresubmitPromptWarning(PresubmitResult):
    def __init__(self, message, items, long_text=""):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = "warning"

  class PresubmitNotifyResult(PresubmitResult):
    def __init__(self, message, items, long_text=""):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = "notify"


class MockFile(object):
  def __init__(self, local_path, old_contents, new_contents):
    self._local_path = local_path
    self._new_contents = new_contents
    self._old_contents = old_contents
    self._cached_changed_contents = None

  def ChangedContents(self):
    return self._changed_contents

  def NewContents(self):
    return self._new_contents

  def LocalPath(self):
    return self._local_path

  def IsDirectory(self):
    return False

  def GenerateScmDiff(self):
    result = ""
    for line in difflib.unified_diff(self._old_contents, self._new_contents,
                                     self._local_path, self._local_path):
      result += line
    return result

  # NOTE: This method is a copy of ChangeContents method of AffectedFile in
  # presubmit_support.py
  def ChangedContents(self):
    """Returns a list of tuples (line number, line text) of all new lines.

     This relies on the scm diff output describing each changed code section
     with a line of the form

     ^@@ <old line num>,<old size> <new line num>,<new size> @@$
    """
    if self._cached_changed_contents is not None:
      return self._cached_changed_contents[:]
    self._cached_changed_contents = []
    line_num = 0

    if self.IsDirectory():
      return []

    for line in self.GenerateScmDiff().splitlines():
      m = re.match(r"^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@", line)
      if m:
        line_num = int(m.groups(1)[0])
        continue
      if line.startswith("+") and not line.startswith("++"):
        self._cached_changed_contents.append((line_num, line[1:]))
      if not line.startswith("-"):
        line_num += 1
    return self._cached_changed_contents[:]


class MockChange(object):
  def __init__(self, changed_files):
    self._changed_files = changed_files

  def LocalPaths(self):
    return self._changed_files


class StrictEnumValueCheckerTest(unittest.TestCase):
  TEST_FILE_PATTERN = "changed_file_%s.h"
  MOCK_FILE_LOCAL_PATH = "mock_enum.h"
  START_MARKER = "enum MockEnum {"
  END_MARKER = "  mBoundary"

  def _ReadTextFileContents(self, path):
    """Given a path, returns a list of strings corresponding to the text lines
    in the file. Reads files in text format.

    """
    fo = open(path, "r")
    try:
      contents = fo.readlines()
    finally:
      fo.close()
    return contents

  def _ReadInputFile(self):
    return self._ReadTextFileContents("mock_enum.h")

  def _PrepareTest(self, new_file_path):
    old_contents = self._ReadInputFile()
    if not new_file_path:
      new_contents = []
    else:
      new_contents = self._ReadTextFileContents(new_file_path)
    input_api = MockInputApi()
    mock_file = MockFile(self.MOCK_FILE_LOCAL_PATH,
                         old_contents,
                         new_contents)
    input_api.files.append(mock_file)
    output_api = MockOutputApi()
    return input_api, output_api

  def _RunTest(self, new_file_path):
    input_api, output_api = self._PrepareTest(new_file_path)
    checker = StrictEnumValueChecker(input_api, output_api, self.START_MARKER,
                                     self.END_MARKER, self.MOCK_FILE_LOCAL_PATH)
    results = checker.Run()
    return results

  def testDeleteFile(self):
    results = self._RunTest(new_file_path=None)
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a single warning about file deletion.")

  def testSimpleValidEdit(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "1")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(0, len(results),
                      "We should get no warning for simple edits.")

  def testSingleDeletionOfEntry(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "2")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for an entry deletion.")

  def testSingleRenameOfEntry(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "3")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for an entry rename, even "
                      "though it is not optimal.")

  def testMissingEnumStartOfEntry(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "4")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for a missing enum marker.")

  def testMissingEnumEndOfEntry(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "5")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for a missing enum marker.")

  def testInvertedEnumMarkersOfEntry(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "6")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for inverted enum markers.")

  def testMultipleInvalidEdits(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "7")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(3, len(results),
                      "We should get 3 warnings (one per edit).")

  def testSingleInvalidInserts(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "8")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(1, len(results),
                      "We should get a warning for a single invalid "
                      "insertion inside the enum.")

  def testMulitpleValidInserts(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "9")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(0, len(results),
                      "We should not get a warning mulitple valid edits")

  def testSingleValidDeleteOutsideOfEnum(self):
    results = self._RunTest(self.TEST_FILE_PATTERN % "10")
    # TODO(rpaquay) How to check it's the expected warning?'
    self.assertEquals(0, len(results),
                      "We should not get a warning for a deletion outside of "
                      "the enum")


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