#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS 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 nightly_revert_checker."""

from __future__ import print_function

import io
import unittest
from unittest.mock import patch

import cros_utils.tiny_render as tiny_render
import get_upstream_patch
import nightly_revert_checker
import revert_checker

# pylint: disable=protected-access


class Test(unittest.TestCase):
  """Tests for nightly_revert_checker."""

  def test_email_rendering_works_for_singular_revert(self):
    def prettify_sha(sha: str) -> tiny_render.Piece:
      return 'pretty_' + sha

    def get_sha_description(sha: str) -> tiny_render.Piece:
      return 'subject_' + sha

    email = nightly_revert_checker._generate_revert_email(
        repository_name='${repo}',
        friendly_name='${name}',
        sha='${sha}',
        prettify_sha=prettify_sha,
        get_sha_description=get_sha_description,
        new_reverts=[
            revert_checker.Revert(sha='${revert_sha}',
                                  reverted_sha='${reverted_sha}')
        ])

    expected_email = nightly_revert_checker._Email(
        subject='[revert-checker/${repo}] new revert discovered across ${name}',
        body=[
            'It looks like there may be a new revert across ${name} (',
            'pretty_${sha}',
            ').',
            tiny_render.line_break,
            tiny_render.line_break,
            'That is:',
            tiny_render.UnorderedList([[
                'pretty_${revert_sha}',
                ' (appears to revert ',
                'pretty_${reverted_sha}',
                '): ',
                'subject_${revert_sha}',
            ]]),
            tiny_render.line_break,
            'PTAL and consider reverting them locally.',
        ])

    self.assertEqual(email, expected_email)

  def test_email_rendering_works_for_multiple_reverts(self):
    def prettify_sha(sha: str) -> tiny_render.Piece:
      return 'pretty_' + sha

    def get_sha_description(sha: str) -> tiny_render.Piece:
      return 'subject_' + sha

    email = nightly_revert_checker._generate_revert_email(
        repository_name='${repo}',
        friendly_name='${name}',
        sha='${sha}',
        prettify_sha=prettify_sha,
        get_sha_description=get_sha_description,
        new_reverts=[
            revert_checker.Revert(sha='${revert_sha1}',
                                  reverted_sha='${reverted_sha1}'),
            revert_checker.Revert(sha='${revert_sha2}',
                                  reverted_sha='${reverted_sha2}'),
            # Keep this out-of-order to check that we sort based on SHAs
            revert_checker.Revert(sha='${revert_sha0}',
                                  reverted_sha='${reverted_sha0}'),
        ])

    expected_email = nightly_revert_checker._Email(
        subject='[revert-checker/${repo}] new reverts discovered across '
        '${name}',
        body=[
            'It looks like there may be new reverts across ${name} (',
            'pretty_${sha}',
            ').',
            tiny_render.line_break,
            tiny_render.line_break,
            'These are:',
            tiny_render.UnorderedList([
                [
                    'pretty_${revert_sha0}',
                    ' (appears to revert ',
                    'pretty_${reverted_sha0}',
                    '): ',
                    'subject_${revert_sha0}',
                ],
                [
                    'pretty_${revert_sha1}',
                    ' (appears to revert ',
                    'pretty_${reverted_sha1}',
                    '): ',
                    'subject_${revert_sha1}',
                ],
                [
                    'pretty_${revert_sha2}',
                    ' (appears to revert ',
                    'pretty_${reverted_sha2}',
                    '): ',
                    'subject_${revert_sha2}',
                ],
            ]),
            tiny_render.line_break,
            'PTAL and consider reverting them locally.',
        ])

    self.assertEqual(email, expected_email)

  def test_llvm_ebuild_parsing_appears_to_function(self):
    llvm_ebuild = io.StringIO('\n'.join((
        'foo',
        '#LLVM_HASH="123"',
        'LLVM_HASH="123" # comment',
        'LLVM_NEXT_HASH="456"',
    )))

    shas = nightly_revert_checker._parse_llvm_ebuild_for_shas(llvm_ebuild)
    self.assertEqual(shas, [
        ('llvm', '123'),
        ('llvm-next', '456'),
    ])

  def test_llvm_ebuild_parsing_fails_if_both_hashes_arent_present(self):
    bad_bodies = [
        '',
        'LLVM_HASH="123" # comment',
        'LLVM_NEXT_HASH="123" # comment',
        'LLVM_NEXT_HASH="123" # comment\n#LLVM_HASH="123"',
    ]

    for bad in bad_bodies:
      with self.assertRaises(ValueError) as e:
        nightly_revert_checker._parse_llvm_ebuild_for_shas(io.StringIO(bad))

      self.assertIn('Failed to detect SHAs', str(e.exception))

  @patch('revert_checker.find_reverts')
  @patch('get_upstream_patch.get_from_upstream')
  def test_do_cherrypick_is_called(self, do_cherrypick, find_reverts):
    find_reverts.return_value = [
        revert_checker.Revert('12345abcdef', 'fedcba54321')
    ]
    nightly_revert_checker.do_cherrypick(chroot_path='/path/to/chroot',
                                         llvm_dir='/path/to/llvm',
                                         interesting_shas=[('12345abcdef',
                                                            'fedcba54321')],
                                         state={},
                                         reviewers=['meow@chromium.org'],
                                         cc=['purr@chromium.org'])

    do_cherrypick.assert_called_once()
    find_reverts.assert_called_once()

  @patch('revert_checker.find_reverts')
  @patch('get_upstream_patch.get_from_upstream')
  def test_do_cherrypick_handles_cherrypick_error(self, do_cherrypick,
                                                  find_reverts):
    find_reverts.return_value = [
        revert_checker.Revert('12345abcdef', 'fedcba54321')
    ]
    do_cherrypick.side_effect = get_upstream_patch.CherrypickError(
        'Patch at 12345abcdef already exists in PATCHES.json')
    nightly_revert_checker.do_cherrypick(chroot_path='/path/to/chroot',
                                         llvm_dir='/path/to/llvm',
                                         interesting_shas=[('12345abcdef',
                                                            'fedcba54321')],
                                         state={},
                                         reviewers=['meow@chromium.org'],
                                         cc=['purr@chromium.org'])

    do_cherrypick.assert_called_once()
    find_reverts.assert_called_once()


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