# Copyright 2018 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 unittest

from src.test.py.bazel import test_base


class FirstTimeUseTest(test_base.TestBase):

  def _FailWithOutput(self, output):
    self.fail('FAIL:\n | %s\n---' % '\n | '.join(output))

  def testNoPythonRequirement(self):
    """Regression test for https://github.com/bazelbuild/bazel/issues/6463."""
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    exit_code, stdout, stderr = self.RunBazel(['info', 'release'])
    self.AssertExitCode(exit_code, 0, stderr)
    for line in stdout + stderr:
      if 'python' in line and 'not found on PATH' in line:
        self._FailWithOutput(stdout + stderr)

  def _AssertBazelRunBinaryOutput(self, exit_code, stdout, stderr):
    self.AssertExitCode(exit_code, 0, stderr)
    found_hello = found_arg_a = found_arg_bc = False
    for line in stdout + stderr:
      if 'ERROR' in line and 'needs a shell' in line:
        self._FailWithOutput(stdout + stderr)
      if not found_hello and 'hello python' in line:
        found_hello = True
      elif not found_arg_a and 'arg[1]=(a)':
        found_arg_a = True
      elif not found_arg_bc and 'arg[2]=(b c)':
        found_arg_bc = True
        break
    if not found_hello or not found_arg_a or not found_arg_bc:
      self._FailWithOutput(stdout + stderr)

  def testNoBashRequiredForSimpleBazelRun(self):
    """Regression test for https://github.com/bazelbuild/bazel/issues/8229."""
    self.CreateWorkspaceWithDefaultRepos('WORKSPACE')
    self.ScratchFile('foo/BUILD', [
        'py_binary(',
        '    name = "x",'
        '    srcs = ["x.py"],',
        '    args = ["a", "\'b c\'"],',
        ')',
    ])
    self.ScratchFile('foo/x.py', [
        'from __future__ import print_function',
        'import sys',
        'print("hello python")',
        'for i in range(len(sys.argv)):',
        '    print("arg%d=(%s)" % (i, sys.argv[i]))',
    ])

    if test_base.TestBase.IsWindows():
      exit_code, stdout, stderr = self.RunBazel([
          'run',
          # "bazel run" needs no Bash on Windows, so this call should succeed.
          '--shell_executable=',
          '//foo:x',
      ])

      self._AssertBazelRunBinaryOutput(exit_code, stdout, stderr)
    else:
      exit_code, stdout, stderr = self.RunBazel([
          'run',
          # Run fails because we provide no shell. Platforms other than
          # Windows always use Bash for "bazel run".
          '--shell_executable=',
          '//foo:x',
      ])
      self.AssertNotExitCode(exit_code, 0, stderr)
      found_error = False
      for line in stdout + stderr:
        if 'ERROR' in line and 'needs a shell' in line:
          found_error = True
          break
      if not found_error:
        self._FailWithOutput(stdout + stderr)

      # Run succeeds because there is a shell.
      exit_code, stdout, stderr = self.RunBazel(['run', '//foo:x'])
      self._AssertBazelRunBinaryOutput(exit_code, stdout, stderr)


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