# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Test the filelib module."""

from __future__ import print_function

import os
import shutil
import subprocess

from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib.paygen import filelib
from chromite.lib.paygen import utils


class TestFileManipulation(cros_test_lib.TestCase):
  """Test cases for filelib."""

  FILE1 = 'file1a'
  FILE2 = 'file2'
  SUBDIR = 'subdir'
  SUBFILE = '%s/file1b' % SUBDIR
  FILE_GLOB = 'file1*'

  FILE1_CONTENTS = 'Howdy doody there dandy'
  FILE2_CONTENTS = 'Once upon a time in a galaxy far far away.'
  SUBFILE_CONTENTS = 'Five little monkeys jumped on the bed.'

  def _SetUpTempdir(self, tempdir):
    with open(os.path.join(tempdir, self.FILE1), 'w') as out1:
      out1.write(self.FILE1_CONTENTS)

    with open(os.path.join(tempdir, self.FILE2), 'w') as out2:
      out2.write(self.FILE2_CONTENTS)

    subdir = os.path.join(tempdir, self.SUBDIR)
    osutils.SafeMakedirs(subdir)

    with open(os.path.join(tempdir, self.SUBFILE), 'w') as out3:
      out3.write(self.SUBFILE_CONTENTS)

  def testIntegrationScript(self):
    dir1 = None
    dir2 = None
    try:
      dir1 = utils.CreateTmpDir('filelib_unittest1-')
      dir2 = utils.CreateTmpDir('filelib_unittest2-')

      self._SetUpTempdir(dir1)

      dir1_file1 = os.path.join(dir1, self.FILE1)
      dir1_file2 = os.path.join(dir1, self.FILE2)
      dir1_subfile = os.path.join(dir1, self.SUBFILE)
      dir1_top_files = [dir1_file1, dir1_file2]
      dir1_deep_files = dir1_top_files + [dir1_subfile]

      dir2_file1 = os.path.join(dir2, self.FILE1)
      dir2_file2 = os.path.join(dir2, self.FILE2)
      dir2_subdir = os.path.join(dir2, self.SUBDIR)
      dir2_subfile = os.path.join(dir2, self.SUBFILE)
      dir2_top_files = [dir2_file1, dir2_file2]
      dir2_deep_files = dir2_top_files + [dir2_subfile]

      # Test Exists.
      for dir1_path in dir1_deep_files:
        self.assertTrue(filelib.Exists(dir1_path))
      for dir2_path in dir2_deep_files:
        self.assertFalse(filelib.Exists(dir2_path))

      # Test ListFiles with various options.
      self.assertEqual(set(dir1_top_files),
                       set(filelib.ListFiles(dir1)))
      self.assertEqual(set(dir1_deep_files),
                       set(filelib.ListFiles(dir1, recurse=True)))
      self.assertEqual(sorted(dir1_deep_files),
                       filelib.ListFiles(dir1, recurse=True, sort=True))
      self.assertEqual(set([dir1_file1, dir1_subfile]),
                       set(filelib.ListFiles(dir1, recurse=True,
                                             filepattern=self.FILE_GLOB)))
      # Test CopyFiles from dir1 to dir2.
      self.assertEqual(set(dir2_deep_files),
                       set(filelib.CopyFiles(dir1, dir2)))
      for dir2_path in dir2_deep_files:
        self.assertTrue(filelib.Exists(dir2_path))

      # Test Cmp.
      self.assertTrue(filelib.Cmp(dir1_file1, dir2_file1))
      self.assertTrue(filelib.Cmp(dir2_file2, dir1_file2))
      self.assertFalse(filelib.Cmp(dir1_file2, dir2_file1))

      # Test RemoveDirContents.
      filelib.RemoveDirContents(dir2_subdir)
      self.assertTrue(filelib.Exists(dir2_subdir, as_dir=True))
      self.assertFalse(filelib.Exists(dir2_subfile))
      filelib.RemoveDirContents(dir2)
      self.assertTrue(filelib.Exists(dir2, as_dir=True))
      for dir2_path in dir2_deep_files:
        self.assertFalse(filelib.Exists(dir2_path))

      filelib.RemoveDirContents(dir1)
      self.assertTrue(filelib.Exists(dir1, as_dir=True))
      for dir1_path in dir1_deep_files:
        self.assertFalse(filelib.Exists(dir1_path))

    finally:
      for d in (dir1, dir2):
        if d and os.path.isdir(d):
          shutil.rmtree(d)


class TestFileLib(cros_test_lib.MoxTempDirTestCase):
  """Test filelib module."""

  def _MD5Sum(self, file_path):
    """Use RunCommand to get the md5sum of a file."""
    md5_path = '/usr/bin/md5sum'
    if not os.path.exists(md5_path):
      self.fail('%s is required to test MD5 logic.')
    cmd = [md5_path, file_path]
    return cros_build_lib.RunCommand(
        cmd, redirect_stdout=True).output.split(' ')[0]

  def _SHA1Sum(self, file_path):
    """Use sha1sum utility to get SHA1 of a file."""
    # The sha1sum utility gives SHA1 in base 16 encoding.  We need
    # base 64, so use combination of xxd and base64 utilities.
    proc1 = subprocess.Popen(['sha1sum', file_path], stdout=subprocess.PIPE)
    proc2 = subprocess.Popen(['cut', '-f1', '-d', ' '], stdin=proc1.stdout,
                             stdout=subprocess.PIPE)
    proc3 = subprocess.Popen(['xxd', '-r', '-p'], stdin=proc2.stdout,
                             stdout=subprocess.PIPE)
    proc4 = subprocess.Popen(['base64'], stdin=proc3.stdout,
                             stdout=subprocess.PIPE)
    result = proc4.communicate()
    return result[0][:-1]

  def _SHA256Sum(self, file_path):
    """Use sha256 utility to get SHA256 of a file."""
    # The sha256sum utility gives SHA256 in base 16 encoding.  We need
    # base 64, so use combination of xxd and base64 utilities.
    proc1 = subprocess.Popen(['sha256sum', file_path], stdout=subprocess.PIPE)
    proc2 = subprocess.Popen(['cut', '-f1', '-d', ' '], stdin=proc1.stdout,
                             stdout=subprocess.PIPE)
    proc3 = subprocess.Popen(['xxd', '-r', '-p'], stdin=proc2.stdout,
                             stdout=subprocess.PIPE)
    proc4 = subprocess.Popen(['base64'], stdin=proc3.stdout,
                             stdout=subprocess.PIPE)
    result = proc4.communicate()
    return result[0][:-1]

  def testMD5Sum(self):
    """Test MD5Sum output with the /usr/bin/md5sum binary."""
    file_path = os.path.abspath(__file__)
    self.assertEqual(self._MD5Sum(file_path), filelib.MD5Sum(file_path))

  def testShaSums(self):
    file_path = os.path.abspath(__file__)
    expected_sha1 = self._SHA1Sum(file_path)
    expected_sha256 = self._SHA256Sum(file_path)
    sha1, sha256 = filelib.ShaSums(file_path)
    self.assertEqual(expected_sha1, sha1)
    self.assertEqual(expected_sha256, sha256)

  def testCmp(self):
    path1 = '/some/local/path'
    path2 = '/other/local/path'

    self.mox.StubOutWithMock(filelib.os.path, 'exists')
    self.mox.StubOutWithMock(filelib.filecmp, 'cmp')

    # Set up the test replay script.
    # Run 1, both exist, are different.
    filelib.os.path.exists(path1).AndReturn(True)
    filelib.os.path.exists(path2).AndReturn(True)
    filelib.filecmp.cmp(path1, path2).AndReturn(True)
    # Run 2, both exist, are different.
    filelib.os.path.exists(path1).AndReturn(True)
    filelib.os.path.exists(path2).AndReturn(True)
    filelib.filecmp.cmp(path1, path2).AndReturn(False)
    # Run 3, second file missing.
    filelib.os.path.exists(path1).AndReturn(True)
    filelib.os.path.exists(path2).AndReturn(False)
    self.mox.ReplayAll()

    # Run the test verification.
    self.assertTrue(filelib.Cmp(path1, path2))
    self.assertFalse(filelib.Cmp(path1, path2))
    self.assertFalse(filelib.Cmp(path1, path2))
    self.mox.VerifyAll()

  def testCopy(self):
    path1 = '/some/local/path'
    path2 = '/other/local/path'
    relative_path = 'relative.bin'

    self.mox.StubOutWithMock(filelib, 'Exists')
    self.mox.StubOutWithMock(osutils, 'SafeMakedirs')
    self.mox.StubOutWithMock(filelib.shutil, 'copy2')

    # Set up the test replay script.
    # Run 1, path2 directory exists.
    filelib.Exists(os.path.dirname(path2), as_dir=True).AndReturn(True)
    filelib.shutil.copy2(path1, path2)
    # Run 2, path2 directory does not exist.
    filelib.Exists(os.path.dirname(path2), as_dir=True).AndReturn(False)
    osutils.SafeMakedirs(os.path.dirname(path2))
    filelib.shutil.copy2(path1, path2)

    # Run 3, there is target directory is '.', don't test existence.
    filelib.shutil.copy2(path1, relative_path)
    self.mox.ReplayAll()

    # Run the test verifications, three times.
    filelib.Copy(path1, path2)
    filelib.Copy(path1, path2)
    filelib.Copy(path1, relative_path)
    self.mox.VerifyAll()

  def testSize(self):
    path = '/some/local/path'
    size = 100

    self.mox.StubOutWithMock(filelib.os.path, 'isfile')
    self.mox.StubOutWithMock(filelib.os, 'stat')

    # Set up the test replay script.
    # Run 1, success.
    filelib.os.path.isfile(path).AndReturn(True)
    filelib.os.stat(path).AndReturn(cros_test_lib.EasyAttr(st_size=size))
    # Run 2, file not found.
    filelib.os.path.isfile(path).AndReturn(False)
    self.mox.ReplayAll()

    # Run the test verification.
    self.assertEqual(size, filelib.Size(path))
    self.assertRaises(filelib.MissingFileError, filelib.Size, path)
    self.mox.VerifyAll()

  def testExists(self):
    path = '/some/local/path'
    result = 'TheResult'

    self.mox.StubOutWithMock(filelib.os.path, 'isdir')
    self.mox.StubOutWithMock(filelib.os.path, 'isfile')

    # Set up the test replay script.
    # Run 1, as file.
    filelib.os.path.isfile(path).AndReturn(result)
    # Run 2, as dir.
    filelib.os.path.isdir(path).AndReturn(result)
    self.mox.ReplayAll()

    # Run the test verification.
    self.assertEqual(result, filelib.Exists(path))
    self.assertEqual(result, filelib.Exists(path, as_dir=True))
    self.mox.VerifyAll()

  def _CreateSimpleFile(self, *args):
    contents = 'Not important, can be anything'
    for path in args:
      with open(path, 'w') as out:
        out.write(contents)

  def testRemove(self):
    # pylint: disable=E1101
    path1 = os.path.join(self.tempdir, 'file1')
    path2 = os.path.join(self.tempdir, 'file2')
    missing_path = os.path.join(self.tempdir, 'missing')
    subdir = os.path.join(self.tempdir, 'subdir')
    subpath1 = os.path.join(subdir, 'file3')
    subpath2 = os.path.join(subdir, 'file4')

    # Test remove on path that does not exist.
    self.assertRaises(filelib.MissingFileError, filelib.Remove, path1)
    self.assertFalse(filelib.Remove(path1, ignore_no_match=True))

    # Test remove on simple file.
    self._CreateSimpleFile(path1)
    self.assertTrue(filelib.Remove(path1))
    self.assertRaises(filelib.MissingFileError, filelib.Remove, path1)
    self.assertFalse(filelib.Remove(path1, ignore_no_match=True))

    # Test remove on more than one file.
    self._CreateSimpleFile(path1, path2)
    self.assertTrue(filelib.Remove(path1, path2))

    # Test remove on multiple files, with one missing.
    self._CreateSimpleFile(path1, path2)
    self.assertRaises(filelib.MissingFileError, filelib.Remove,
                      path1, missing_path, path2)
    # First path1 removed, but path2 not because it was after missing.
    self.assertFalse(filelib.Exists(path1))
    self.assertTrue(filelib.Exists(path2))

    # Test remove multiple files, one missing, with ignore_no_match True.
    self._CreateSimpleFile(path1, path2)
    self.assertFalse(filelib.Remove(path1, missing_path, path2,
                                    ignore_no_match=True))
    self.assertFalse(filelib.Exists(path1))
    self.assertFalse(filelib.Exists(path2))

    # Test recursive Remove.
    os.makedirs(subdir)
    self._CreateSimpleFile(path1, path2, subpath1, subpath2)
    self.assertTrue(filelib.Remove(path1, path2, subdir, recurse=True))
    self.assertFalse(filelib.Exists(path1))
    self.assertFalse(filelib.Exists(subpath1))

    # Test recursive Remove with one missing path.
    os.makedirs(subdir)
    self._CreateSimpleFile(path1, path2, subpath1, subpath2)
    self.assertRaises(filelib.MissingFileError, filelib.Remove,
                      path1, subdir, missing_path, path2, recurse=True)
    self.assertFalse(filelib.Exists(path1))
    self.assertTrue(filelib.Exists(path2))
    self.assertFalse(filelib.Exists(subpath1))

    # Test recursive Remove with one missing path and ignore_no_match True.
    os.makedirs(subdir)
    self._CreateSimpleFile(path1, path2, subpath1, subpath2)
    self.assertFalse(filelib.Remove(path1, subdir, missing_path, path2,
                                    recurse=True, ignore_no_match=True))
    self.assertFalse(filelib.Exists(path1))
    self.assertFalse(filelib.Exists(path2))
    self.assertFalse(filelib.Exists(subpath1))
