#!/usr/bin/env vpython3

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

from __future__ import absolute_import
import os
import shutil
import tempfile
import textwrap
import unittest

import PRESUBMIT
# pylint: disable=line-too-long
from presubmit_test_mocks import MockInputApi, MockOutputApi, MockFile, MockChange


class CheckBugEntryFieldTest(unittest.TestCase):
    def testCommitMessageBugEntryWithNoError(self):
        mock_input_api = MockInputApi()
        mock_output_api = MockOutputApi()
        mock_input_api.change = MockChange([], ['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 = MockChange([], ['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 testCommitMessageBugEntryWithoutPrefix(self):
        mock_input_api = MockInputApi()
        mock_output_api = MockOutputApi()
        mock_input_api.change = MockChange([], ['1234'])
        errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
                                                      mock_output_api)
        self.assertEqual(1, len(errors))
        self.assertEqual(('Bug entry requires issue tracker prefix, '
                          'e.g. webrtc:1234'), str(errors[0]))

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

    def testCommitMessageBugEntrySupportInternalBugReference(self):
        mock_input_api = MockInputApi()
        mock_output_api = MockOutputApi()
        setattr(mock_input_api.change, 'BUG', 'b/12345')
        errors = PRESUBMIT.CheckCommitMessageBugEntry(mock_input_api,
                                                      mock_output_api)
        self.assertEqual(0, len(errors))
        setattr(mock_input_api.change, 'BUG', 'b/12345, webrtc:1234')
        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, lambda x: True)
        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, lambda x: True)
        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_library("bar_foo") {
        if (is_win) {
          sources = [
            "bar.cc",
          ],
        }
        if (is_ios) {
          sources = [
            "bar.mm",
          ],
        }
      }
      rtc_library("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_library("bar_foo") {
        if (is_win) {
          sources = [
            "bar.cc",
          ],
        }
        if (foo_bar) {
          sources += [
            "bar.mm",
          ],
        }
      }
      rtc_library("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 len(sources) == 3, 'This function accepts a list of 3 source files'
        self._GenerateBuildFile(
            textwrap.dedent("""
      rtc_static_library("bar_foo") {
        sources = [
          "%s",
          "%s",
          "%s",
        ],
      }
      rtc_library("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)


class CheckAssertUsageTest(unittest.TestCase):
    def setUp(self):
        self.input_api = MockInputApi()
        self.output_api = MockOutputApi()
        self._content_with_assert = ['void Foo() {', '    assert(true);', '}']
        self._content_without_assert = ['void Foo() {', '    RTC_CHECK(true);', '}']

    def testDetectsAssertInCcFile(self):
        self.input_api.files = [
            MockFile('with_assert.cc', self._content_with_assert),
            MockFile('without_assert.cc', self._content_without_assert),
        ]
        errors = PRESUBMIT.CheckAssertUsage(self.input_api,
                                            self.output_api, lambda x: True)
        self.assertEqual(1, len(errors))
        self.assertEqual('with_assert.cc', errors[0].items[0])

    def testDetectsAssertInHeaderFile(self):
        self.input_api.files = [
            MockFile('with_assert.h', self._content_with_assert),
            MockFile('without_assert.h', self._content_without_assert),
        ]
        errors = PRESUBMIT.CheckAssertUsage(self.input_api,
                                            self.output_api, lambda x: True)
        self.assertEqual(1, len(errors))
        self.assertEqual('with_assert.h', errors[0].items[0])

    def testDetectsAssertInObjCFile(self):
        self.input_api.files = [
            MockFile('with_assert.m', self._content_with_assert),
            MockFile('without_assert.m', self._content_without_assert),
        ]
        errors = PRESUBMIT.CheckAssertUsage(self.input_api,
                                            self.output_api, lambda x: True)
        self.assertEqual(1, len(errors))
        self.assertEqual('with_assert.m', errors[0].items[0])

    def testDetectsAssertInObjCppFile(self):
        self.input_api.files = [
            MockFile('with_assert.mm', self._content_with_assert),
            MockFile('without_assert.mm', self._content_without_assert),
        ]
        errors = PRESUBMIT.CheckAssertUsage(self.input_api,
                                            self.output_api, lambda x: True)
        self.assertEqual(1, len(errors))
        self.assertEqual('with_assert.mm', errors[0].items[0])

    def testDoesntDetectAssertInOtherFiles(self):
        self.input_api.files = [
            MockFile('with_assert.cpp', self._content_with_assert),
        ]
        errors = PRESUBMIT.CheckAssertUsage(self.input_api,
                                            self.output_api, lambda x: True)
        self.assertEqual(0, len(errors))


class CheckCpplintExceptionsTest(unittest.TestCase):
    def testAllPathsExist(self):
        repo_root = os.path.dirname(os.path.abspath(__file__))
        non_existing = [
            path for path in PRESUBMIT.CPPLINT_EXCEPTIONS
            if not os.path.exists(os.path.join(repo_root, *path.split('/')))
        ]
        self.assertEqual([], non_existing)


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