# Copyright (c) 2016 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 os
import re
import sys
import unittest
import PRESUBMIT

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from PRESUBMIT_test_mocks import MockOutputApi, MockChange

class MockInputApi(object):
  """ Mocked input api for unit testing of presubmit.
  This lets us mock things like file system operations and changed files.
  """
  def __init__(self):
    self.re = re
    self.os_path = os.path
    self.files = []
    self.is_committing = False

  def AffectedFiles(self):
    return self.files

  def AffectedSourceFiles(self):
    return self.files

  def ReadFile(self, f):
    """ Returns the mock contents of f if they've been defined.
    """
    for api_file in self.files:
        if api_file.LocalPath() == f:
            return api_file.NewContents()


class MockFile(object):
  """Mock file object so that presubmit can act invoke file system operations.
  """
  def __init__(self, local_path, new_contents):
    self._local_path = local_path
    self._new_contents = new_contents
    self._changed_contents = ([(i + 1, l) for i, l in enumerate(new_contents)])

  def ChangedContents(self):
    return self._changed_contents

  def NewContents(self):
    return self._new_contents

  def LocalPath(self):
    return self._local_path

  def AbsoluteLocalPath(self):
    return self._local_path
# Format string used as the contents of a mock sync.proto in order to
# test presubmit parsing of EntitySpecifics definition in that file.
MOCK_PROTOFILE_CONTENTS = ('\n'
  'message EntitySpecifics {\n'
  '//comment\n'
  '\n'
  'optional AutofillSpecifics autofill = 123;\n'
  'optional AppSpecifics app = 456;\n'
  'optional AppSettingSpecifics app_setting = 789;\n'
  '//comment\n'
  '}\n')


# Format string used as the contents of a mock model_type.cc
# in order to test presubmit parsing of the ModelTypeInfoMap in that file.
MOCK_MODELTYPE_CONTENTS =('\n'
  'const ModelTypeInfo kModelTypeInfoMap[] = {\n'
  '{APP_SETTINGS, "APP_SETTING", "app_settings", "App settings",\n'
  'sync_pb::EntitySpecifics::kAppSettingFieldNumber, 13},\n'
  '%s\n'
  '};\n')


class ModelTypeInfoChangeTest(unittest.TestCase):
  """Unit testing class that contains tests for sync/PRESUBMIT.py.
  """
  def test_ValidChangeMultiLine(self):
    results = self._testChange('{APPS, "APP", "apps", "Apps",\n'
     'sync_pb::EntitySpecifics::kAppFieldNumber, 12},')
    self.assertEqual(0, len(results))

  def testValidChangeToleratesPluralization(self):
    results = self._testChange('{APPS, "APP", "apps", "App",\n'
      'sync_pb::EntitySpecifics::kAppFieldNumber, 12},')
    self.assertEqual(0, len(results))

  def testValidChangeGrandfatheredEntry(self):
    results = self._testChange('{PROXY_TABS, "", "", "Tabs", -1, 25},')
    self.assertEqual(0, len(results))

  def testInvalidChangeMismatchedNotificationType(self):
    results = self._testChange('{AUTOFILL, "AUTOFILL_WRONG", "autofill",\n'
     '"Autofill",sync_pb::EntitySpecifics::kAutofillFieldNumber, 6},')
    self.assertEqual(1, len(results))
    self.assertTrue('notification type' in results[0].message)

  def testInvalidChangeInconsistentModelType(self):
    results = self._testChange('{AUTOFILL, "AUTOFILL", "autofill",\n'
     '"Autofill Extra",sync_pb::EntitySpecifics::kAutofillFieldNumber, 6},')
    self.assertEqual(1, len(results))
    self.assertTrue('model type string' in results[0].message)

  def testInvalidChangeNotTitleCased(self):
    results = self._testChange('{AUTOFILL, "AUTOFILL", "autofill",\n'
     '"autofill",sync_pb::EntitySpecifics::kAutofillFieldNumber, 6},')
    self.assertEqual(1, len(results))
    self.assertTrue('title' in results[0].message)

  def testInvalidChangeInconsistentRootTag(self):
    results = self._testChange('{AUTOFILL, "AUTOFILL", "autofill root",\n'
     '"Autofill",sync_pb::EntitySpecifics::kAutofillFieldNumber, 6},')
    self.assertEqual(1, len(results))
    self.assertTrue('root tag' in results[0].message)

  def testInvalidChangeDuplicatedValues(self):
    results = self._testChange('{APP_SETTINGS, "APP_SETTING",\n'
      '"app_settings", "App settings",\n'
      'sync_pb::EntitySpecifics::kAppSettingFieldNumber, 13},\n')
    self.assertEqual(6, len(results))
    self.assertTrue('APP_SETTINGS' in results[0].message)

  def _testChange(self, modeltype_literal):
    mock_input_api = MockInputApi()
    mock_input_api.files = [
      MockFile(os.path.abspath('./protocol/sync.proto'),
        MOCK_PROTOFILE_CONTENTS),
      MockFile(os.path.abspath('./syncable/model_type.cc'),
        MOCK_MODELTYPE_CONTENTS % (modeltype_literal))
    ]

    return PRESUBMIT.CheckChangeOnCommit(mock_input_api, MockOutputApi())
if __name__ == '__main__':
  unittest.main()
