# -*- coding: utf-8 -*-
# Copyright 2015 Google Inc. 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.
"""Tests for yapf.file_resources."""

import contextlib
import os
import shutil
import tempfile
import unittest

from yapf.yapflib import errors
from yapf.yapflib import file_resources
from yapf.yapflib import py3compat

from yapftests import utils


@contextlib.contextmanager
def _restore_working_dir():
  curdir = os.getcwd()
  try:
    yield
  finally:
    os.chdir(curdir)


@contextlib.contextmanager
def _exists_mocked_in_module(module, mock_implementation):
  unmocked_exists = getattr(module, 'exists')
  setattr(module, 'exists', mock_implementation)
  try:
    yield
  finally:
    setattr(module, 'exists', unmocked_exists)


class GetExcludePatternsForDir(unittest.TestCase):

  def setUp(self):  # pylint: disable=g-missing-super-call
    self.test_tmpdir = tempfile.mkdtemp()

  def tearDown(self):  # pylint: disable=g-missing-super-call
    shutil.rmtree(self.test_tmpdir)

  def test_get_exclude_file_patterns_from_yapfignore(self):
    local_ignore_file = os.path.join(self.test_tmpdir, '.yapfignore')
    ignore_patterns = ['temp/**/*.py', 'temp2/*.py']
    with open(local_ignore_file, 'w') as f:
      f.writelines('\n'.join(ignore_patterns))

    self.assertEqual(
        sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
        sorted(ignore_patterns))

  def test_get_exclude_file_patterns_from_yapfignore_with_wrong_syntax(self):
    local_ignore_file = os.path.join(self.test_tmpdir, '.yapfignore')
    ignore_patterns = ['temp/**/*.py', './wrong/syntax/*.py']
    with open(local_ignore_file, 'w') as f:
      f.writelines('\n'.join(ignore_patterns))

    with self.assertRaises(errors.YapfError):
      file_resources.GetExcludePatternsForDir(self.test_tmpdir)

  def test_get_exclude_file_patterns_from_pyproject(self):
    try:
      import tomli
    except ImportError:
      return
    local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
    ignore_patterns = ['temp/**/*.py', 'temp2/*.py']
    with open(local_ignore_file, 'w') as f:
      f.write('[tool.yapfignore]\n')
      f.write('ignore_patterns=[')
      f.writelines('\n,'.join(['"{}"'.format(p) for p in ignore_patterns]))
      f.write(']')

    self.assertEqual(
        sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
        sorted(ignore_patterns))

  @unittest.skipUnless(py3compat.PY36, 'Requires Python 3.6')
  def test_get_exclude_file_patterns_from_pyproject_with_wrong_syntax(self):
    try:
      import tomli
    except ImportError:
      return
    local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
    ignore_patterns = ['temp/**/*.py', './wrong/syntax/*.py']
    with open(local_ignore_file, 'w') as f:
      f.write('[tool.yapfignore]\n')
      f.write('ignore_patterns=[')
      f.writelines('\n,'.join(['"{}"'.format(p) for p in ignore_patterns]))
      f.write(']')

    with self.assertRaises(errors.YapfError):
      file_resources.GetExcludePatternsForDir(self.test_tmpdir)

  def test_get_exclude_file_patterns_from_pyproject_no_ignore_section(self):
    try:
      import tomli
    except ImportError:
      return
    local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
    ignore_patterns = []
    open(local_ignore_file, 'w').close()

    self.assertEqual(
        sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
        sorted(ignore_patterns))

  def test_get_exclude_file_patterns_from_pyproject_ignore_section_empty(self):
    try:
      import tomli
    except ImportError:
      return
    local_ignore_file = os.path.join(self.test_tmpdir, 'pyproject.toml')
    ignore_patterns = []
    with open(local_ignore_file, 'w') as f:
      f.write('[tool.yapfignore]\n')

    self.assertEqual(
        sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
        sorted(ignore_patterns))

  def test_get_exclude_file_patterns_with_no_config_files(self):
    ignore_patterns = []

    self.assertEqual(
        sorted(file_resources.GetExcludePatternsForDir(self.test_tmpdir)),
        sorted(ignore_patterns))


class GetDefaultStyleForDirTest(unittest.TestCase):

  def setUp(self):  # pylint: disable=g-missing-super-call
    self.test_tmpdir = tempfile.mkdtemp()

  def tearDown(self):  # pylint: disable=g-missing-super-call
    shutil.rmtree(self.test_tmpdir)

  def test_no_local_style(self):
    test_file = os.path.join(self.test_tmpdir, 'file.py')
    style_name = file_resources.GetDefaultStyleForDir(test_file)
    self.assertEqual(style_name, 'pep8')

  def test_no_local_style_custom_default(self):
    test_file = os.path.join(self.test_tmpdir, 'file.py')
    style_name = file_resources.GetDefaultStyleForDir(
        test_file, default_style='custom-default')
    self.assertEqual(style_name, 'custom-default')

  def test_with_local_style(self):
    # Create an empty .style.yapf file in test_tmpdir
    style_file = os.path.join(self.test_tmpdir, '.style.yapf')
    open(style_file, 'w').close()

    test_filename = os.path.join(self.test_tmpdir, 'file.py')
    self.assertEqual(style_file,
                     file_resources.GetDefaultStyleForDir(test_filename))

    test_filename = os.path.join(self.test_tmpdir, 'dir1', 'file.py')
    self.assertEqual(style_file,
                     file_resources.GetDefaultStyleForDir(test_filename))

  def test_setup_config(self):
    # An empty setup.cfg file should not be used
    setup_config = os.path.join(self.test_tmpdir, 'setup.cfg')
    open(setup_config, 'w').close()

    test_dir = os.path.join(self.test_tmpdir, 'dir1')
    style_name = file_resources.GetDefaultStyleForDir(test_dir)
    self.assertEqual(style_name, 'pep8')

    # One with a '[yapf]' section should be used
    with open(setup_config, 'w') as f:
      f.write('[yapf]\n')
    self.assertEqual(setup_config,
                     file_resources.GetDefaultStyleForDir(test_dir))

  def test_pyproject_toml(self):
    # An empty pyproject.toml file should not be used
    try:
      import tomli
    except ImportError:
      return

    pyproject_toml = os.path.join(self.test_tmpdir, 'pyproject.toml')
    open(pyproject_toml, 'w').close()

    test_dir = os.path.join(self.test_tmpdir, 'dir1')
    style_name = file_resources.GetDefaultStyleForDir(test_dir)
    self.assertEqual(style_name, 'pep8')

    # One with a '[tool.yapf]' section should be used
    with open(pyproject_toml, 'w') as f:
      f.write('[tool.yapf]\n')
    self.assertEqual(pyproject_toml,
                     file_resources.GetDefaultStyleForDir(test_dir))

  def test_local_style_at_root(self):
    # Test behavior of files located on the root, and under root.
    rootdir = os.path.abspath(os.path.sep)
    test_dir_at_root = os.path.join(rootdir, 'dir1')
    test_dir_under_root = os.path.join(rootdir, 'dir1', 'dir2')

    # Fake placing only a style file at the root by mocking `os.path.exists`.
    style_file = os.path.join(rootdir, '.style.yapf')

    def mock_exists_implementation(path):
      return path == style_file

    with _exists_mocked_in_module(file_resources.os.path,
                                  mock_exists_implementation):
      # Both files should find the style file at the root.
      default_style_at_root = file_resources.GetDefaultStyleForDir(
          test_dir_at_root)
      self.assertEqual(style_file, default_style_at_root)
      default_style_under_root = file_resources.GetDefaultStyleForDir(
          test_dir_under_root)
      self.assertEqual(style_file, default_style_under_root)


def _touch_files(filenames):
  for name in filenames:
    open(name, 'a').close()


class GetCommandLineFilesTest(unittest.TestCase):

  def setUp(self):  # pylint: disable=g-missing-super-call
    self.test_tmpdir = tempfile.mkdtemp()
    self.old_dir = os.getcwd()

  def tearDown(self):  # pylint: disable=g-missing-super-call
    os.chdir(self.old_dir)
    shutil.rmtree(self.test_tmpdir)

  def _make_test_dir(self, name):
    fullpath = os.path.normpath(os.path.join(self.test_tmpdir, name))
    os.makedirs(fullpath)
    return fullpath

  def test_find_files_not_dirs(self):
    tdir1 = self._make_test_dir('test1')
    tdir2 = self._make_test_dir('test2')
    file1 = os.path.join(tdir1, 'testfile1.py')
    file2 = os.path.join(tdir2, 'testfile2.py')
    _touch_files([file1, file2])

    self.assertEqual(
        file_resources.GetCommandLineFiles([file1, file2],
                                           recursive=False,
                                           exclude=None), [file1, file2])
    self.assertEqual(
        file_resources.GetCommandLineFiles([file1, file2],
                                           recursive=True,
                                           exclude=None), [file1, file2])

  def test_nonrecursive_find_in_dir(self):
    tdir1 = self._make_test_dir('test1')
    tdir2 = self._make_test_dir('test1/foo')
    file1 = os.path.join(tdir1, 'testfile1.py')
    file2 = os.path.join(tdir2, 'testfile2.py')
    _touch_files([file1, file2])

    self.assertRaises(
        errors.YapfError,
        file_resources.GetCommandLineFiles,
        command_line_file_list=[tdir1],
        recursive=False,
        exclude=None)

  def test_recursive_find_in_dir(self):
    tdir1 = self._make_test_dir('test1')
    tdir2 = self._make_test_dir('test2/testinner/')
    tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx')
    files = [
        os.path.join(tdir1, 'testfile1.py'),
        os.path.join(tdir2, 'testfile2.py'),
        os.path.join(tdir3, 'testfile3.py'),
    ]
    _touch_files(files)

    self.assertEqual(
        sorted(
            file_resources.GetCommandLineFiles([self.test_tmpdir],
                                               recursive=True,
                                               exclude=None)), sorted(files))

  def test_recursive_find_in_dir_with_exclude(self):
    tdir1 = self._make_test_dir('test1')
    tdir2 = self._make_test_dir('test2/testinner/')
    tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx')
    files = [
        os.path.join(tdir1, 'testfile1.py'),
        os.path.join(tdir2, 'testfile2.py'),
        os.path.join(tdir3, 'testfile3.py'),
    ]
    _touch_files(files)

    self.assertEqual(
        sorted(
            file_resources.GetCommandLineFiles([self.test_tmpdir],
                                               recursive=True,
                                               exclude=['*test*3.py'])),
        sorted([
            os.path.join(tdir1, 'testfile1.py'),
            os.path.join(tdir2, 'testfile2.py'),
        ]))

  def test_find_with_excluded_hidden_dirs(self):
    tdir1 = self._make_test_dir('.test1')
    tdir2 = self._make_test_dir('test_2')
    tdir3 = self._make_test_dir('test.3')
    files = [
        os.path.join(tdir1, 'testfile1.py'),
        os.path.join(tdir2, 'testfile2.py'),
        os.path.join(tdir3, 'testfile3.py'),
    ]
    _touch_files(files)

    actual = file_resources.GetCommandLineFiles([self.test_tmpdir],
                                                recursive=True,
                                                exclude=['*.test1*'])

    self.assertEqual(
        sorted(actual),
        sorted([
            os.path.join(tdir2, 'testfile2.py'),
            os.path.join(tdir3, 'testfile3.py'),
        ]))

  def test_find_with_excluded_hidden_dirs_relative(self):
    """Test find with excluded hidden dirs.

    A regression test against a specific case where a hidden directory (one
    beginning with a period) is being excluded, but it is also an immediate
    child of the current directory which has been specified in a relative
    manner.

    At its core, the bug has to do with overzealous stripping of "./foo" so that
    it removes too much from "./.foo" .
    """
    tdir1 = self._make_test_dir('.test1')
    tdir2 = self._make_test_dir('test_2')
    tdir3 = self._make_test_dir('test.3')
    files = [
        os.path.join(tdir1, 'testfile1.py'),
        os.path.join(tdir2, 'testfile2.py'),
        os.path.join(tdir3, 'testfile3.py'),
    ]
    _touch_files(files)

    # We must temporarily change the current directory, so that we test against
    # patterns like ./.test1/file instead of /tmp/foo/.test1/file
    with _restore_working_dir():

      os.chdir(self.test_tmpdir)
      actual = file_resources.GetCommandLineFiles(
          [os.path.relpath(self.test_tmpdir)],
          recursive=True,
          exclude=['*.test1*'])

      self.assertEqual(
          sorted(actual),
          sorted([
              os.path.join(
                  os.path.relpath(self.test_tmpdir), os.path.basename(tdir2),
                  'testfile2.py'),
              os.path.join(
                  os.path.relpath(self.test_tmpdir), os.path.basename(tdir3),
                  'testfile3.py'),
          ]))

  def test_find_with_excluded_dirs(self):
    tdir1 = self._make_test_dir('test1')
    tdir2 = self._make_test_dir('test2/testinner/')
    tdir3 = self._make_test_dir('test3/foo/bar/bas/xxx')
    files = [
        os.path.join(tdir1, 'testfile1.py'),
        os.path.join(tdir2, 'testfile2.py'),
        os.path.join(tdir3, 'testfile3.py'),
    ]
    _touch_files(files)

    os.chdir(self.test_tmpdir)

    found = sorted(
        file_resources.GetCommandLineFiles(['test1', 'test2', 'test3'],
                                           recursive=True,
                                           exclude=[
                                               'test1',
                                               'test2/testinner/',
                                           ]))

    self.assertEqual(
        found, ['test3/foo/bar/bas/xxx/testfile3.py'.replace("/", os.path.sep)])

    found = sorted(
        file_resources.GetCommandLineFiles(['.'],
                                           recursive=True,
                                           exclude=[
                                               'test1',
                                               'test3',
                                           ]))

    self.assertEqual(
        found, ['./test2/testinner/testfile2.py'.replace("/", os.path.sep)])

  def test_find_with_excluded_current_dir(self):
    with self.assertRaises(errors.YapfError):
      file_resources.GetCommandLineFiles([], False, exclude=['./z'])


class IsPythonFileTest(unittest.TestCase):

  def setUp(self):  # pylint: disable=g-missing-super-call
    self.test_tmpdir = tempfile.mkdtemp()

  def tearDown(self):  # pylint: disable=g-missing-super-call
    shutil.rmtree(self.test_tmpdir)

  def test_with_py_extension(self):
    file1 = os.path.join(self.test_tmpdir, 'testfile1.py')
    self.assertTrue(file_resources.IsPythonFile(file1))

  def test_empty_without_py_extension(self):
    file1 = os.path.join(self.test_tmpdir, 'testfile1')
    self.assertFalse(file_resources.IsPythonFile(file1))
    file2 = os.path.join(self.test_tmpdir, 'testfile1.rb')
    self.assertFalse(file_resources.IsPythonFile(file2))

  def test_python_shebang(self):
    file1 = os.path.join(self.test_tmpdir, 'testfile1')
    with open(file1, 'w') as f:
      f.write(u'#!/usr/bin/python\n')
    self.assertTrue(file_resources.IsPythonFile(file1))

    file2 = os.path.join(self.test_tmpdir, 'testfile2.run')
    with open(file2, 'w') as f:
      f.write(u'#! /bin/python2\n')
    self.assertTrue(file_resources.IsPythonFile(file1))

  def test_with_latin_encoding(self):
    file1 = os.path.join(self.test_tmpdir, 'testfile1')
    with py3compat.open_with_encoding(file1, mode='w', encoding='latin-1') as f:
      f.write(u'#! /bin/python2\n')
    self.assertTrue(file_resources.IsPythonFile(file1))

  def test_with_invalid_encoding(self):
    file1 = os.path.join(self.test_tmpdir, 'testfile1')
    with open(file1, 'w') as f:
      f.write(u'#! /bin/python2\n')
      f.write(u'# -*- coding: iso-3-14159 -*-\n')
    self.assertFalse(file_resources.IsPythonFile(file1))


class IsIgnoredTest(unittest.TestCase):

  def test_root_path(self):
    self.assertTrue(file_resources.IsIgnored('media', ['media']))
    self.assertFalse(file_resources.IsIgnored('media', ['media/*']))

  def test_sub_path(self):
    self.assertTrue(file_resources.IsIgnored('media/a', ['*/a']))
    self.assertTrue(file_resources.IsIgnored('media/b', ['media/*']))
    self.assertTrue(file_resources.IsIgnored('media/b/c', ['*/*/c']))

  def test_trailing_slash(self):
    self.assertTrue(file_resources.IsIgnored('z', ['z']))
    self.assertTrue(file_resources.IsIgnored('z', ['z' + os.path.sep]))


class BufferedByteStream(object):

  def __init__(self):
    self.stream = py3compat.BytesIO()

  def getvalue(self):  # pylint: disable=invalid-name
    return self.stream.getvalue().decode('utf-8')

  @property
  def buffer(self):
    return self.stream


class WriteReformattedCodeTest(unittest.TestCase):

  @classmethod
  def setUpClass(cls):  # pylint: disable=g-missing-super-call
    cls.test_tmpdir = tempfile.mkdtemp()

  @classmethod
  def tearDownClass(cls):  # pylint: disable=g-missing-super-call
    shutil.rmtree(cls.test_tmpdir)

  def test_write_to_file(self):
    s = u'foobar\n'
    with utils.NamedTempFile(dirname=self.test_tmpdir) as (f, fname):
      file_resources.WriteReformattedCode(
          fname, s, in_place=True, encoding='utf-8')
      f.flush()

      with open(fname) as f2:
        self.assertEqual(f2.read(), s)

  def test_write_to_stdout(self):
    s = u'foobar'
    stream = BufferedByteStream() if py3compat.PY3 else py3compat.StringIO()
    with utils.stdout_redirector(stream):
      file_resources.WriteReformattedCode(
          None, s, in_place=False, encoding='utf-8')
    self.assertEqual(stream.getvalue(), s)

  def test_write_encoded_to_stdout(self):
    s = '\ufeff# -*- coding: utf-8 -*-\nresult = "passed"\n'  # pylint: disable=anomalous-unicode-escape-in-string # noqa
    stream = BufferedByteStream() if py3compat.PY3 else py3compat.StringIO()
    with utils.stdout_redirector(stream):
      file_resources.WriteReformattedCode(
          None, s, in_place=False, encoding='utf-8')
    self.assertEqual(stream.getvalue(), s)


class LineEndingTest(unittest.TestCase):

  def test_line_ending_linefeed(self):
    lines = ['spam\n', 'spam\n']
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\n')

  def test_line_ending_carriage_return(self):
    lines = ['spam\r', 'spam\r']
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\r')

  def test_line_ending_combo(self):
    lines = ['spam\r\n', 'spam\r\n']
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\r\n')

  def test_line_ending_weighted(self):
    lines = [
        'spam\n',
        'spam\n',
        'spam\r',
        'spam\r\n',
    ]
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\n')

  def test_line_ending_empty(self):
    lines = []
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\n')

  def test_line_ending_no_newline(self):
    lines = ['spam']
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\n')

  def test_line_ending_tie(self):
    lines = [
        'spam\n',
        'spam\n',
        'spam\r\n',
        'spam\r\n',
    ]
    actual = file_resources.LineEnding(lines)
    self.assertEqual(actual, '\n')


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