#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2019 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 git_llvm_rev."""

import unittest

import git_llvm_rev
import llvm_project
from git_llvm_rev import MAIN_BRANCH


def get_llvm_config() -> git_llvm_rev.LLVMConfig:
  return git_llvm_rev.LLVMConfig(
      dir=llvm_project.get_location(), remote='origin')


class Test(unittest.TestCase):
  """Test cases for git_llvm_rev."""

  def rev_to_sha_with_round_trip(self, rev: git_llvm_rev.Rev) -> str:
    config = get_llvm_config()
    sha = git_llvm_rev.translate_rev_to_sha(config, rev)
    roundtrip_rev = git_llvm_rev.translate_sha_to_rev(config, sha)
    self.assertEqual(roundtrip_rev, rev)
    return sha

  def test_sha_to_rev_on_base_sha_works(self) -> None:
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(
            branch=MAIN_BRANCH, number=git_llvm_rev.base_llvm_revision))
    self.assertEqual(sha, git_llvm_rev.base_llvm_sha)

  def test_sha_to_rev_prior_to_base_rev_works(self) -> None:
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=375000))
    self.assertEqual(sha, '2f6da767f13b8fd81f840c211d405fea32ac9db7')

  def test_sha_to_rev_after_base_rev_works(self) -> None:
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=375506))
    self.assertEqual(sha, '3bf7fddeb05655d9baed4cc69e13535c677ed1dd')

  def test_llvm_svn_parsing_runs_ignore_reverts(self) -> None:
    # This commit has a revert that mentions the reverted llvm-svn in the
    # commit message.

    # Commit which performed the revert
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=374895))
    self.assertEqual(sha, '1731fc88d1fa1fa55edd056db73a339b415dd5d6')

    # Commit that was reverted
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=374841))
    self.assertEqual(sha, '2a1386c81de504b5bda44fbecf3f7b4cdfd748fc')

  def test_imaginary_revs_raise(self) -> None:
    with self.assertRaises(ValueError) as r:
      git_llvm_rev.translate_rev_to_sha(
          get_llvm_config(),
          git_llvm_rev.Rev(branch=MAIN_BRANCH, number=9999999))

    self.assertIn('Try updating your tree?', str(r.exception))

  def test_merge_commits_count_as_one_commit_crbug1041079(self) -> None:
    # This CL merged _a lot_ of commits in. Verify a few hand-computed
    # properties about it.
    merge_sha_rev_number = 4496 + git_llvm_rev.base_llvm_revision
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=merge_sha_rev_number))
    self.assertEqual(sha, '0f0d0ed1c78f1a80139a1f2133fad5284691a121')

    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=merge_sha_rev_number - 1))
    self.assertEqual(sha, '6f635f90929da9545dd696071a829a1a42f84b30')

    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=merge_sha_rev_number + 1))
    self.assertEqual(sha, '199700a5cfeedf227619f966aa3125cef18bc958')

  # NOTE: The below tests have _zz_ in their name as an optimization. Iterating
  # on a quick test is painful when these larger tests come before it and take
  # 7secs to run. Python's unittest module guarantees tests are run in
  # alphabetical order by their method name, so...
  #
  # If you're wondering, the slow part is `git branch -r --contains`. I imagine
  # it's going to be very cold code, so I'm not inclined to optimize it much.

  def test_zz_branch_revs_work_after_merge_points_and_svn_cutoff(self) -> None:
    # Arbitrary 9.x commit without an attached llvm-svn: value.
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch='release/9.x', number=366670))
    self.assertEqual(sha, '4e858e4ac00b59f064da4e1f7e276916e7d296aa')

  def test_zz_branch_revs_work_at_merge_points(self) -> None:
    rev_number = 366426
    backing_sha = 'c89a3d78f43d81b9cff7b9248772ddf14d21b749'

    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch=MAIN_BRANCH, number=rev_number))
    self.assertEqual(sha, backing_sha)

    # Note that this won't round-trip: since this commit is on the main
    # branch, we'll pick main for this. That's fine.
    sha = git_llvm_rev.translate_rev_to_sha(
        get_llvm_config(),
        git_llvm_rev.Rev(branch='release/9.x', number=rev_number))
    self.assertEqual(sha, backing_sha)

  def test_zz_branch_revs_work_after_merge_points(self) -> None:
    # Picking the commit on the 9.x branch after the merge-base for that +
    # main. Note that this is where llvm-svn numbers should diverge from
    # ours, and are therefore untrustworthy. The commit for this *does* have a
    # different `llvm-svn:` string than we should have.
    sha = self.rev_to_sha_with_round_trip(
        git_llvm_rev.Rev(branch='release/9.x', number=366427))
    self.assertEqual(sha, '2cf681a11aea459b50d712abc7136f7129e4d57f')


# FIXME: When release/10.x happens, it may be nice to have a test-case
# generally covering that, since it's the first branch that we have to travel
# back to the base commit for.

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