#!/usr/bin/env vpython3
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for gold_utils.

Example usage:
  vpython3 gold_utils_test.py
"""

#pylint: disable=protected-access

import contextlib
import os
from pathlib import Path
import sys
import tempfile
import unittest
from unittest import mock

path_root = Path(__file__).parents[2]
sys.path.append(str(path_root))

from pylib.constants import host_paths
from pylib.utils import gold_utils

with host_paths.SysPath(host_paths.BUILD_PATH):
  from skia_gold_common import unittest_utils

from pyfakefs import fake_filesystem_unittest  # pylint: disable=import-error

createSkiaGoldArgs = unittest_utils.createSkiaGoldArgs


def assertArgWith(test, arg_list, arg, value):
  i = arg_list.index(arg)
  test.assertEqual(arg_list[i + 1], value)


class AndroidSkiaGoldSessionDiffTest(fake_filesystem_unittest.TestCase):
  def setUp(self):
    self.setUpPyfakefs()
    self._working_dir = tempfile.mkdtemp()
    self._json_keys = tempfile.NamedTemporaryFile(delete=False).name

  @mock.patch.object(gold_utils.AndroidSkiaGoldSession, '_RunCmdForRcAndOutput')
  def test_commandCommonArgs(self, cmd_mock):
    cmd_mock.return_value = (None, None)
    args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=False)
    sgp = gold_utils.AndroidSkiaGoldProperties(args)
    session = gold_utils.AndroidSkiaGoldSession(self._working_dir,
                                                sgp,
                                                self._json_keys,
                                                'corpus',
                                                instance='instance')
    session.Diff('name', 'png_file', None)
    call_args = cmd_mock.call_args[0][0]
    self.assertIn('diff', call_args)
    assertArgWith(self, call_args, '--corpus', 'corpus')
    # TODO(skbug.com/10610): Remove the -public once we go back to using the
    # non-public instance, or add a second test for testing that the correct
    # instance is chosen if we decide to support both depending on what the
    # user is authenticated for.
    assertArgWith(self, call_args, '--instance', 'instance-public')
    assertArgWith(self, call_args, '--input', 'png_file')
    assertArgWith(self, call_args, '--test', 'name')
    # TODO(skbug.com/10611): Re-add this assert and remove the check for the
    # absence of the directory once we switch back to using the proper working
    # directory.
    # assertArgWith(self, call_args, '--work-dir', self._working_dir)
    self.assertNotIn(self._working_dir, call_args)
    i = call_args.index('--out-dir')
    # The output directory should be a subdirectory of the working directory.
    self.assertIn(self._working_dir, call_args[i + 1])


class AndroidSkiaGoldSessionDiffLinksTest(fake_filesystem_unittest.TestCase):
  class FakeArchivedFile:
    def __init__(self, path):
      self.name = path

    def Link(self):
      return 'file://' + self.name

  class FakeOutputManager:
    def __init__(self):
      self.output_dir = tempfile.mkdtemp()

    @contextlib.contextmanager
    def ArchivedTempfile(self, image_name, _, __):
      filepath = os.path.join(self.output_dir, image_name)
      yield AndroidSkiaGoldSessionDiffLinksTest.FakeArchivedFile(filepath)

  def setUp(self):
    self.setUpPyfakefs()
    self._working_dir = tempfile.mkdtemp()
    self._json_keys = tempfile.NamedTemporaryFile(delete=False).name
    self._timestamp_patcher = mock.patch.object(gold_utils, '_GetTimestamp')
    self._timestamp_mock = self._timestamp_patcher.start()
    self.addCleanup(self._timestamp_patcher.stop)

  def test_outputManagerUsed(self):
    self._timestamp_mock.return_value = 'ts0'
    args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=True)
    sgp = gold_utils.AndroidSkiaGoldProperties(args)
    session = gold_utils.AndroidSkiaGoldSession(self._working_dir, sgp,
                                                self._json_keys, None, None)
    with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f:
      f.write('input')
    with open(os.path.join(self._working_dir, 'closest-closesthash.png'),
              'w') as f:
      f.write('closest')
    with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f:
      f.write('diff')

    output_manager = AndroidSkiaGoldSessionDiffLinksTest.FakeOutputManager()
    session._StoreDiffLinks('foo', output_manager, self._working_dir)

    copied_input = os.path.join(output_manager.output_dir, 'given_foo_ts0.png')
    copied_closest = os.path.join(output_manager.output_dir,
                                  'closest_foo_ts0.png')
    copied_diff = os.path.join(output_manager.output_dir, 'diff_foo_ts0.png')
    with open(copied_input) as f:
      self.assertEqual(f.read(), 'input')
    with open(copied_closest) as f:
      self.assertEqual(f.read(), 'closest')
    with open(copied_diff) as f:
      self.assertEqual(f.read(), 'diff')

    self.assertEqual(session.GetGivenImageLink('foo'), 'file://' + copied_input)
    self.assertEqual(session.GetClosestImageLink('foo'),
                     'file://' + copied_closest)
    self.assertEqual(session.GetDiffImageLink('foo'), 'file://' + copied_diff)

  def test_diffLinksDoNotClobber(self):
    """Tests that multiple calls to store links does not clobber files."""

    def side_effect():
      side_effect.count += 1
      return f'ts{side_effect.count}'

    side_effect.count = -1
    self._timestamp_mock.side_effect = side_effect

    args = createSkiaGoldArgs(git_revision='a', local_pixel_tests=True)
    sgp = gold_utils.AndroidSkiaGoldProperties(args)
    session = gold_utils.AndroidSkiaGoldSession(self._working_dir, sgp,
                                                self._json_keys, None, None)
    with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f:
      f.write('first input')
    with open(os.path.join(self._working_dir, 'closest-closesthash.png'),
              'w') as f:
      f.write('first closest')
    with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f:
      f.write('first diff')

    output_manager = AndroidSkiaGoldSessionDiffLinksTest.FakeOutputManager()
    session._StoreDiffLinks('foo', output_manager, self._working_dir)

    # Store links normally once.
    first_copied_input = os.path.join(output_manager.output_dir,
                                      'given_foo_ts0.png')
    first_copied_closest = os.path.join(output_manager.output_dir,
                                        'closest_foo_ts0.png')
    first_copied_diff = os.path.join(output_manager.output_dir,
                                     'diff_foo_ts0.png')
    with open(first_copied_input) as f:
      self.assertEqual(f.read(), 'first input')
    with open(first_copied_closest) as f:
      self.assertEqual(f.read(), 'first closest')
    with open(first_copied_diff) as f:
      self.assertEqual(f.read(), 'first diff')

    with open(os.path.join(self._working_dir, 'input-inputhash.png'), 'w') as f:
      f.write('second input')
    with open(os.path.join(self._working_dir, 'closest-closesthash.png'),
              'w') as f:
      f.write('second closest')
    with open(os.path.join(self._working_dir, 'diff.png'), 'w') as f:
      f.write('second diff')

    self.assertEqual(session.GetGivenImageLink('foo'),
                     'file://' + first_copied_input)
    self.assertEqual(session.GetClosestImageLink('foo'),
                     'file://' + first_copied_closest)
    self.assertEqual(session.GetDiffImageLink('foo'),
                     'file://' + first_copied_diff)

    # Store links again and check that the new data is surfaced.
    session._StoreDiffLinks('foo', output_manager, self._working_dir)

    second_copied_input = os.path.join(output_manager.output_dir,
                                       'given_foo_ts1.png')
    second_copied_closest = os.path.join(output_manager.output_dir,
                                         'closest_foo_ts1.png')
    second_copied_diff = os.path.join(output_manager.output_dir,
                                      'diff_foo_ts1.png')
    with open(second_copied_input) as f:
      self.assertEqual(f.read(), 'second input')
    with open(second_copied_closest) as f:
      self.assertEqual(f.read(), 'second closest')
    with open(second_copied_diff) as f:
      self.assertEqual(f.read(), 'second diff')

    self.assertEqual(session.GetGivenImageLink('foo'),
                     'file://' + second_copied_input)
    self.assertEqual(session.GetClosestImageLink('foo'),
                     'file://' + second_copied_closest)
    self.assertEqual(session.GetDiffImageLink('foo'),
                     'file://' + second_copied_diff)

    # Check to make sure the first images still exist on disk and are unchanged.
    with open(first_copied_input) as f:
      self.assertEqual(f.read(), 'first input')
    with open(first_copied_closest) as f:
      self.assertEqual(f.read(), 'first closest')
    with open(first_copied_diff) as f:
      self.assertEqual(f.read(), 'first diff')


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