# pylint: disable=g-bad-file-header
# Copyright 2017 The Bazel Authors. 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.

import os
import threading
import unittest
from six.moves import SimpleHTTPServer
from six.moves import socketserver
from src.test.py.bazel import test_base


class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
  """A helper class to launcher a threaded http server."""
  pass


class BazelExternalRepositoryTest(test_base.TestBase):

  _http_server = None

  def StartHttpServer(self):
    """Runs a simple http server to serve files under current directory."""
    # Port 0 means to select an arbitrary unused port
    host, port = 'localhost', 0
    http_handler = SimpleHTTPServer.SimpleHTTPRequestHandler
    server = ThreadedTCPServer((host, port), http_handler)
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    self._http_server = server

  def StopHttpServer(self):
    """Shutdown and clean up the http server."""
    if self._http_server:
      self._http_server.shutdown()
      self._http_server.server_close()

  def setUp(self):
    test_base.TestBase.setUp(self)
    for f in ['six-1.10.0.tar.gz', 'archive_with_symlink.zip']:
      self.CopyFile(self.Rlocation('io_bazel/src/test/py/bazel/testdata/'
                                   'bazel_external_repository_test/' + f), f)
    self.StartHttpServer()

  def tearDown(self):
    test_base.TestBase.tearDown(self)
    self.StopHttpServer()

  def testNewHttpArchive(self):
    ip, port = self._http_server.server_address
    rule_definition = [
        'load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")',
        'http_archive(',
        '    name = "six_archive",',
        '    urls = ["http://%s:%s/six-1.10.0.tar.gz"],' % (ip, port),
        '    sha256 = '
        '"105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a",',
        '    strip_prefix = "six-1.10.0",',
        '    build_file = "@//third_party:six.BUILD",',
        ')',
    ]
    build_file = [
        'py_library(',
        '  name = "six",',
        '  srcs = ["six.py"],',
        ')',
    ]
    rule_definition.extend(self.GetDefaultRepoRules())
    self.ScratchFile('WORKSPACE', rule_definition)
    self.ScratchFile('BUILD')
    self.ScratchFile('third_party/BUILD')
    self.ScratchFile('third_party/six.BUILD', build_file)

    exit_code, _, stderr = self.RunBazel(['build', '@six_archive//...'])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))

    fetching_disabled_msg = 'fetching is disabled'

    # Changing the mtime of the BUILD file shouldn't invalidate it.
    os.utime(self.Path('third_party/six.BUILD'), (100, 200))
    exit_code, _, stderr = self.RunBazel(
        ['build', '--nofetch', '@six_archive//...'])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))
    self.assertNotIn(fetching_disabled_msg, os.linesep.join(stderr))

    # Check that --nofetch prints a warning if the BUILD file is changed.
    self.ScratchFile('third_party/six.BUILD', build_file + ['"a noop string"'])
    exit_code, _, stderr = self.RunBazel(
        ['build', '--nofetch', '@six_archive//...'])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))
    self.assertIn(fetching_disabled_msg, os.linesep.join(stderr))

    # Test repository reloading after BUILD file changes.
    self.ScratchFile('third_party/six.BUILD', build_file + ['foobar'])
    exit_code, _, stderr = self.RunBazel(['build', '@six_archive//...'])
    self.assertEqual(exit_code, 1, os.linesep.join(stderr))
    self.assertIn('name \'foobar\' is not defined', os.linesep.join(stderr))

  def testNewHttpArchiveWithSymlinks(self):
    ip, port = self._http_server.server_address
    rule_definition = [
        'load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")',
        'http_archive(',
        '    name = "archive_with_symlink",',
        '    urls = ["http://%s:%s/archive_with_symlink.zip"],' % (ip, port),
        '    build_file = "@//:archive_with_symlink.BUILD",',
        ')',
    ]
    rule_definition.extend(self.GetDefaultRepoRules())
    self.ScratchFile('WORKSPACE', rule_definition)
    # In the archive, A is a symlink pointing to B
    self.ScratchFile('archive_with_symlink.BUILD', [
        'filegroup(',
        '    name = "file-A",',
        '    srcs = ["A"],',
        ')',
    ])
    self.ScratchFile('BUILD')
    exit_code, _, stderr = self.RunBazel([
        'build',
        '@archive_with_symlink//:file-A',
    ])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))

  def _CreatePyWritingStarlarkRule(self, print_string):
    self.ScratchFile('repo/foo.bzl', [
        'def _impl(ctx):',
        '  ctx.actions.write(',
        '      output = ctx.outputs.out,',
        '      content = """from __future__ import print_function',
        'print("%s")""",' % print_string,
        '  )',
        '  return [DefaultInfo(files = depset(direct = [ctx.outputs.out]))]',
        '',
        'gen_py = rule(',
        '    implementation = _impl,',
        "    outputs = {'out': '%{name}.py'},",
        ')',
    ])

  def testNewLocalRepositoryNoticesFileChangeInRepoRoot(self):
    """Regression test for https://github.com/bazelbuild/bazel/issues/7063."""
    rule_definition = [
        'load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")',
        'new_local_repository(',
        '    name = "r",',
        '    path = "./repo",',
        '    build_file_content = "exports_files([\'foo.bzl\'])",',
        ')',
    ]
    rule_definition.extend(self.GetDefaultRepoRules())
    self.ScratchFile('WORKSPACE', rule_definition)
    self.CreateWorkspaceWithDefaultRepos('repo/WORKSPACE')
    self._CreatePyWritingStarlarkRule('hello!')
    self.ScratchFile('BUILD', [
        'load("@r//:foo.bzl", "gen_py")',
        'gen_py(name = "gen")',
        'py_binary(name = "bin", srcs = [":gen"], main = "gen.py")',
    ])

    exit_code, stdout, stderr = self.RunBazel(['run', '//:bin'])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))
    self.assertIn('hello!', os.linesep.join(stdout))

    # Modify the definition of the Starlark rule in the external repository.
    # The py_binary rule should notice this and rebuild.
    self._CreatePyWritingStarlarkRule('world')
    exit_code, stdout, stderr = self.RunBazel(['run', '//:bin'])
    self.assertEqual(exit_code, 0, os.linesep.join(stderr))
    self.assertNotIn('hello!', os.linesep.join(stdout))
    self.assertIn('world', os.linesep.join(stdout))


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