# -*- 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 toml
    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 toml
    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 toml
    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 toml
    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 toml
    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 overzelous 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')


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