# -*- 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 os

import mock

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)
    ])
