# -*- coding: utf-8 -*-
# Copyright 2018 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.

"""Tests for scripts/repo_sync_manifest."""

from __future__ import print_function

import mock
import os

from chromite.cbuildbot import manifest_version
from chromite.cbuildbot import repository
from chromite.lib import cros_test_lib
from chromite.scripts import repo_sync_manifest


class RepoSyncManifestTest(cros_test_lib.RunCommandTempDirTestCase):
  """Unit tests for repo_sync_manifest."""

  INT_MANIFEST_URL = ('https://chrome-internal-review.googlesource.com/'
                      'chromeos/manifest-internal')
  EXT_MANIFEST_URL = ('https://chromium.googlesource.com/chromiumos/manifest')

  MV_INT_URL = ('https://chrome-internal.googlesource.com/chromeos/'
                'manifest-versions')
  MV_EXT_URL = ('https://chromium.googlesource.com/chromiumos/'
                'manifest-versions')

  def setUp(self):
    self.repo_dir = os.path.join(self.tempdir, 'repo')
    self.repo_url = os.path.join(self.tempdir, '.repo/repo')
    self.preload_src = os.path.join(self.tempdir, 'source')
    self.git_cache = os.path.join(self.tempdir, 'git_cache')
    self.manifest = os.path.join(self.tempdir, 'manifest.xml')
    self.mv_ext = os.path.join(self.tempdir, 'mv_ext')
    self.mv_int = os.path.join(self.tempdir, 'mv_int')
    self.manifest_url = 'manifest.com'

    self.repo_mock = self.PatchObject(
        repository, 'RepoRepository', autospec=True)

    self.refresh_manifest_mock = self.PatchObject(
        manifest_version, 'RefreshManifestCheckout', autospec=True)

    self.resolve_buildspec_mock = self.PatchObject(
        manifest_version, 'ResolveBuildspec', autospec=True)

    self.resolve_version_mock = self.PatchObject(
        manifest_version, 'ResolveBuildspecVersion', autospec=True)


  def notestHelp(self):
    with self.assertRaises(SystemExit):
      repo_sync_manifest.main([
          '--help',
      ])

  def testMinimal(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest=None)
    ])

  def testMinimalExternal(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--external',
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.EXT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest=None)
    ])

  def testMinimalManifestUrl(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--manifest-url', self.manifest_url,
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.manifest_url,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest=None)
    ])

  def testBranch(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--branch', 'branch'
    ])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='branch',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest=None)
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

  def testBuildSpec(self):
    self.resolve_buildspec_mock.return_value = 'resolved_buildspec'

    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--buildspec', 'test/spec',
        '--manifest-versions-int', self.mv_int,
    ])

    # Ensure manifest-versions interactions are correct.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [
        mock.call(self.mv_int, self.MV_INT_URL)])
    self.assertEqual(self.resolve_buildspec_mock.mock_calls, [
        mock.call(self.mv_int, 'test/spec')])
    self.assertEqual(self.resolve_version_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest='resolved_buildspec')
    ])

  def testBuildSpecExternal(self):
    self.resolve_buildspec_mock.return_value = 'resolved_buildspec'

    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--buildspec', 'test/spec',
        '--manifest-versions-ext', self.mv_ext,
        '--external',
    ])

    # Ensure manifest-versions interactions are correct.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [
        mock.call(self.mv_ext, self.MV_EXT_URL)])
    self.assertEqual(self.resolve_buildspec_mock.mock_calls, [
        mock.call(self.mv_ext, 'test/spec')])
    self.assertEqual(self.resolve_version_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.EXT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest='resolved_buildspec')
    ])

  def testVersion(self):
    self.resolve_version_mock.return_value = 'resolved_buildspec'

    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--version', '1.2.3',
        '--manifest-versions-int', self.mv_int,
    ])

    # Ensure manifest-versions interactions are correct.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [
        mock.call(self.mv_int, self.MV_INT_URL)])
    self.assertEqual(self.resolve_buildspec_mock.mock_calls, [])
    self.assertEqual(self.resolve_version_mock.mock_calls, [
        mock.call(self.mv_int, '1.2.3')])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest='resolved_buildspec')
    ])

  def testVersionExternal(self):
    self.resolve_version_mock.return_value = 'resolved_buildspec'

    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--version', '1.2.3',
        '--manifest-versions-ext', self.mv_ext,
        '--external',
    ])

    # Ensure manifest-versions interactions are correct.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [
        mock.call(self.mv_ext, self.MV_EXT_URL)])
    self.assertEqual(self.resolve_buildspec_mock.mock_calls, [])
    self.assertEqual(self.resolve_version_mock.mock_calls, [
        mock.call(self.mv_ext, '1.2.3')])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.EXT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest='resolved_buildspec')
    ])

  def testBuildSpecNoManifestVersions(self):
    with self.assertRaises(AssertionError):
      repo_sync_manifest.main([
          '--repo-root', self.repo_dir,
          '--buildspec', 'test/spec',
      ])

    with self.assertRaises(AssertionError):
      repo_sync_manifest.main([
          '--repo-root', self.repo_dir,
          '--buildspec', 'test/spec',
          '--external',
      ])

  def testLocalManifest(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--manifest-file', self.manifest,
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='master',
            git_cache_dir=None,
            repo_url=None,
        ),
        mock.call().Sync(detach=True, local_manifest=self.manifest)
    ])

  def testOptimizations(self):
    repo_sync_manifest.main([
        '--repo-root', self.repo_dir,
        '--copy-repo', self.preload_src,
        '--git-cache', self.git_cache,
        '--repo-url', self.repo_url,
    ])

    # Ensure manifest_versions is not updated.
    self.assertEqual(self.refresh_manifest_mock.mock_calls, [])

    # Ensure RepoRepository created and Sync'd as expected.
    self.assertEqual(self.repo_mock.mock_calls, [
        mock.call(
            directory=self.repo_dir,
            manifest_repo_url=self.INT_MANIFEST_URL,
            branch='master',
            git_cache_dir=self.git_cache,
            repo_url=self.repo_url,
        ),
        mock.call().PreLoad(self.preload_src),
        mock.call().Sync(detach=True, local_manifest=None)
    ])
