# pylint: disable=g-bad-file-header
# Copyright 2019 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.

from __future__ import print_function

import os
import subprocess
import textwrap
import unittest

from src.test.py.bazel import test_base


class MockPythonLines(object):

  NORMAL = textwrap.dedent(r"""\
      if [ "$1" = "-V" ]; then
          echo "Mock Python 2.xyz!"
      else
          echo "I am mock Python!"
      fi
      """).split("\n")

  FAIL = textwrap.dedent(r"""\
      echo "Mock failure!"
      exit 1
      """).split("\n")

  WRONG_VERSION = textwrap.dedent(r"""\
      if [ "$1" = "-V" ]; then
          echo "Mock Python 3.xyz!"
      else
          echo "I am mock Python!"
      fi
      """).split("\n")

  VERSION_ERROR = textwrap.dedent(r"""\
      if [ "$1" = "-V" ]; then
          echo "Error!"
          exit 1
      else
          echo "I am mock Python!"
      fi
      """).split("\n")


# TODO(brandjon): Switch to shutil.which when the test is moved to PY3.
def which(cmd):
  """A poor man's approximation of `shutil.which()` or the `which` command.

  Args:
      cmd: The command (executable) name to lookup; should not contain path
        separators

  Returns:
      The absolute path to the first match in PATH, or None if not found.
  """
  for p in os.environ["PATH"].split(os.pathsep):
    fullpath = os.path.abspath(os.path.join(p, cmd))
    if os.path.exists(fullpath):
      return fullpath
  return None


# TODO(brandjon): Move this test to PY3. Blocked (ironically!) on the fix for
# #4815 being available in the host version of Bazel used to run this test.
class PywrapperTest(test_base.TestBase):
  """Unit tests for pywrapper_template.txt.

  These tests are based on the instantiation of the template for Python 2. They
  ensure that the wrapper can locate, validate, and launch a Python 2 executable
  on PATH. To ensure hermeticity, the tests launch the wrapper with PATH
  restricted to the scratch directory.

  Unix only.
  """

  def setup_tool(self, cmd):
    """Copies a command from its system location to the test directory."""
    path = which(cmd)
    self.assertIsNotNone(
        path, msg="Could not locate '%s' command on PATH" % cmd)
    self.CopyFile(path, os.path.join("dir", cmd), executable=True)

  def setUp(self):
    super(PywrapperTest, self).setUp()

    # Locate script under test.
    wrapper_path = self.Rlocation("io_bazel/tools/python/py2wrapper.sh")
    self.assertIsNotNone(
        wrapper_path, msg="Could not locate py2wrapper.sh in runfiles")
    self.wrapper_path = wrapper_path

    # Setup scratch directory with all executables the script depends on.
    #
    # This is brittle, but we need to make sure we can run the script when only
    # the scratch directory is on PATH, so that we can control whether or not
    # the python executables exist on PATH.
    self.setup_tool("which")
    self.setup_tool("echo")
    self.setup_tool("grep")

  def run_wrapper(self, title_for_logging=None):
    new_env = dict(os.environ)
    new_env["PATH"] = self.Path("dir")
    proc = subprocess.Popen([self.wrapper_path],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            universal_newlines=True,
                            cwd=self.Path("dir"),
                            env=new_env)
    # TODO(brandjon): Add a timeout arg here when upgraded to PY3.
    out, err = proc.communicate()
    if title_for_logging is not None:
      print(textwrap.dedent("""\
          ----------------
          %s
          Exit code: %d
          stdout:
          %s
          stderr:
          %s
          ----------------
          """) % (title_for_logging, proc.returncode, out, err))
    return proc.returncode, out, err

  def assert_wrapper_success(self, returncode, out, err):
    self.assertEqual(returncode, 0, msg="Expected to exit without error")
    self.assertEqual(
        out, "I am mock Python!\n", msg="stdout was not as expected")
    self.assertEqual(err, "", msg="Expected to produce no stderr output")

  def assert_wrapper_failure(self, returncode, out, err, message):
    self.assertEqual(returncode, 1, msg="Expected to exit with error code 1")
    self.assertRegexpMatches(
        err, message, msg="stderr did not contain expected string")

  def test_finds_python2(self):
    self.ScratchFile("dir/python2", MockPythonLines.NORMAL, executable=True)
    returncode, out, err = self.run_wrapper("test_finds_python2")
    self.assert_wrapper_success(returncode, out, err)

  def test_finds_python(self):
    self.ScratchFile("dir/python", MockPythonLines.NORMAL, executable=True)
    returncode, out, err = self.run_wrapper("test_finds_python")
    self.assert_wrapper_success(returncode, out, err)

  def test_prefers_python2(self):
    self.ScratchFile("dir/python2", MockPythonLines.NORMAL, executable=True)
    self.ScratchFile("dir/python", MockPythonLines.FAIL, executable=True)
    returncode, out, err = self.run_wrapper("test_prefers_python2")
    self.assert_wrapper_success(returncode, out, err)

  def test_no_interpreter_found(self):
    returncode, out, err = self.run_wrapper("test_no_interpreter_found")
    self.assert_wrapper_failure(returncode, out, err,
                                "Neither 'python2' nor 'python' were found")

  def test_wrong_version(self):
    self.ScratchFile(
        "dir/python2", MockPythonLines.WRONG_VERSION, executable=True)
    returncode, out, err = self.run_wrapper("test_wrong_version")
    self.assert_wrapper_failure(
        returncode, out, err,
        "version is 'Mock Python 3.xyz!', but we need version 2")

  def test_error_getting_version(self):
    self.ScratchFile(
        "dir/python2", MockPythonLines.VERSION_ERROR, executable=True)
    returncode, out, err = self.run_wrapper("test_error_getting_version")
    self.assert_wrapper_failure(returncode, out, err,
                                "Could not get interpreter version")

  def test_interpreter_not_executable(self):
    self.ScratchFile(
        "dir/python2", MockPythonLines.VERSION_ERROR, executable=False)
    returncode, out, err = self.run_wrapper("test_interpreter_not_executable")
    self.assert_wrapper_failure(returncode, out, err,
                                "Neither 'python2' nor 'python' were found")


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