#!/usr/bin/env python

#  Copyright 2017 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.

import os
import shutil
import tempfile
import textwrap
import unittest

import PRESUBMIT
from presubmit_test_mocks import MockInputApi, MockOutputApi, MockFile


class CheckBugEntryFieldTest(unittest.TestCase):
  def testCommitMessageBugEntryWithNoError(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()
    mock_input_api.change.BUG = 'webrtc:1234'
    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
                                                  mock_output_api)
    self.assertEqual(0, len(errors))

  def testCommitMessageBugEntryReturnError(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()
    mock_input_api.change.BUG = 'webrtc:1234,webrtc=4321'
    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
                                                  mock_output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(('Bogus BUG entry: webrtc=4321. Please specify'
                      ' the issue tracker prefix and the issue number,'
                      ' separated by a colon, e.g. webrtc:123 or'
                      ' chromium:12345.'), str(errors[0]))

  def testCommitMessageBugEntryIsNone(self):
    mock_input_api = MockInputApi()
    mock_output_api = MockOutputApi()
    mock_input_api.change.BUG = 'None'
    errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
                                                  mock_output_api)
    self.assertEqual(0, len(errors))


class CheckNewlineAtTheEndOfProtoFilesTest(unittest.TestCase):

  def setUp(self):
    self.tmp_dir = tempfile.mkdtemp()
    self.proto_file_path = os.path.join(self.tmp_dir, 'foo.proto')
    self.input_api = MockInputApi()
    self.output_api = MockOutputApi()

  def tearDown(self):
    shutil.rmtree(self.tmp_dir, ignore_errors=True)

  def testErrorIfProtoFileDoesNotEndWithNewline(self):
    self._GenerateProtoWithoutNewlineAtTheEnd()
    self.input_api.files = [MockFile(self.proto_file_path)]
    errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(self.input_api,
                                                        self.output_api)
    self.assertEqual(1, len(errors))
    self.assertEqual(
        'File %s must end with exactly one newline.' % self.proto_file_path,
        str(errors[0]))

  def testNoErrorIfProtoFileEndsWithNewline(self):
    self._GenerateProtoWithNewlineAtTheEnd()
    self.input_api.files = [MockFile(self.proto_file_path)]
    errors = PRESUBMIT.CheckNewlineAtTheEndOfProtoFiles(self.input_api,
                                                        self.output_api)
    self.assertEqual(0, len(errors))

  def _GenerateProtoWithNewlineAtTheEnd(self):
    with open(self.proto_file_path, 'w') as f:
      f.write(textwrap.dedent("""
        syntax = "proto2";
        option optimize_for = LITE_RUNTIME;
        package webrtc.audioproc;
      """))

  def _GenerateProtoWithoutNewlineAtTheEnd(self):
    with open(self.proto_file_path, 'w') as f:
      f.write(textwrap.dedent("""
        syntax = "proto2";
        option optimize_for = LITE_RUNTIME;
        package webrtc.audioproc;"""))


class CheckNoMixingSourcesTest(unittest.TestCase):

  def setUp(self):
    self.tmp_dir = tempfile.mkdtemp()
    self.file_path = os.path.join(self.tmp_dir, 'BUILD.gn')
    self.input_api = MockInputApi()
    self.output_api = MockOutputApi()

  def tearDown(self):
    shutil.rmtree(self.tmp_dir, ignore_errors=True)

  def testErrorIfCAndCppAreMixed(self):
    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.cc', 'bar.h'])

  def testErrorIfCAndObjCAreMixed(self):
    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.m', 'bar.h'])

  def testErrorIfCAndObjCppAreMixed(self):
    self._AssertNumberOfErrorsWithSources(1, ['foo.c', 'bar.mm', 'bar.h'])

  def testErrorIfCppAndObjCAreMixed(self):
    self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.m', 'bar.h'])

  def testErrorIfCppAndObjCppAreMixed(self):
    self._AssertNumberOfErrorsWithSources(1, ['foo.cc', 'bar.mm', 'bar.h'])

  def testNoErrorIfOnlyC(self):
    self._AssertNumberOfErrorsWithSources(0, ['foo.c', 'bar.c', 'bar.h'])

  def testNoErrorIfOnlyCpp(self):
    self._AssertNumberOfErrorsWithSources(0, ['foo.cc', 'bar.cc', 'bar.h'])

  def testNoErrorIfOnlyObjC(self):
    self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.m', 'bar.h'])

  def testNoErrorIfOnlyObjCpp(self):
    self._AssertNumberOfErrorsWithSources(0, ['foo.mm', 'bar.mm', 'bar.h'])

  def testNoErrorIfObjCAndObjCppAreMixed(self):
    self._AssertNumberOfErrorsWithSources(0, ['foo.m', 'bar.mm', 'bar.h'])

  def testNoErrorIfSourcesAreInExclusiveIfBranches(self):
    self._GenerateBuildFile(textwrap.dedent("""
      rtc_source_set("bar_foo") {
        if (is_win) {
          sources = [
            "bar.cc",
          ],
        }
        if (is_ios) {
          sources = [
            "bar.mm",
          ],
        }
      }
      rtc_source_set("foo_bar") {
        if (is_win) {
          sources = [
            "foo.cc",
          ],
        }
        if (is_ios) {
          sources = [
            "foo.mm",
          ],
        }
      }
    """))
    self.input_api.files = [MockFile(self.file_path)]
    errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
                                            [MockFile(self.file_path)],
                                            self.output_api)
    self.assertEqual(0, len(errors))

  def testErrorIfSourcesAreNotInExclusiveIfBranches(self):
    self._GenerateBuildFile(textwrap.dedent("""
      rtc_source_set("bar_foo") {
        if (is_win) {
          sources = [
            "bar.cc",
          ],
        }
        if (foo_bar) {
          sources += [
            "bar.mm",
          ],
        }
      }
      rtc_source_set("foo_bar") {
        if (is_win) {
          sources = [
            "foo.cc",
          ],
        }
        if (foo_bar) {
          sources += [
            "foo.mm",
          ],
        }
        if (is_ios) {
          sources = [
            "bar.m",
            "bar.c",
          ],
        }
      }
    """))
    self.input_api.files = [MockFile(self.file_path)]
    errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
                                            [MockFile(self.file_path)],
                                            self.output_api)
    self.assertEqual(1, len(errors))
    self.assertTrue('bar.cc' in str(errors[0]))
    self.assertTrue('bar.mm' in str(errors[0]))
    self.assertTrue('foo.cc' in str(errors[0]))
    self.assertTrue('foo.mm' in str(errors[0]))
    self.assertTrue('bar.m' in str(errors[0]))
    self.assertTrue('bar.c' in str(errors[0]))

  def _AssertNumberOfErrorsWithSources(self, number_of_errors, sources):
    assert 3 == len(sources), 'This function accepts a list of 3 source files'
    self._GenerateBuildFile(textwrap.dedent("""
      rtc_static_library("bar_foo") {
        sources = [
          "%s",
          "%s",
          "%s",
        ],
      }
      rtc_source_set("foo_bar") {
        sources = [
          "%s",
          "%s",
          "%s",
        ],
      }
    """ % (tuple(sources) * 2)))
    self.input_api.files = [MockFile(self.file_path)]
    errors = PRESUBMIT.CheckNoMixingSources(self.input_api,
                                            [MockFile(self.file_path)],
                                            self.output_api)
    self.assertEqual(number_of_errors, len(errors))
    if number_of_errors == 1:
      for source in sources:
        if not source.endswith('.h'):
          self.assertTrue(source in str(errors[0]))

  def _GenerateBuildFile(self, content):
    with open(self.file_path, 'w') as f:
      f.write(content)


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