import unittest
import re

from buildtrigger.triggerutil import matches_ref, raise_if_skipped_build
from buildtrigger.triggerutil import SkipRequestException
from endpoints.building import PreparedBuild

class TestRegex(unittest.TestCase):
  def assertDoesNotMatch(self, ref, filt):
    self.assertFalse(matches_ref(ref, re.compile(filt)))

  def assertMatches(self, ref, filt):
    self.assertTrue(matches_ref(ref, re.compile(filt)))

  def test_matches_ref(self):
    self.assertMatches('ref/heads/master', '.+')
    self.assertMatches('ref/heads/master', 'heads/.+')
    self.assertMatches('ref/heads/master', 'heads/master')
    self.assertMatches('ref/heads/slash/branch', 'heads/slash/branch')
    self.assertMatches('ref/heads/slash/branch', 'heads/.+')

    self.assertDoesNotMatch('ref/heads/foobar', 'heads/master')
    self.assertDoesNotMatch('ref/heads/master', 'tags/master')

    self.assertMatches('ref/heads/master', '(((heads/alpha)|(heads/beta))|(heads/gamma))|(heads/master)')
    self.assertMatches('ref/heads/alpha', '(((heads/alpha)|(heads/beta))|(heads/gamma))|(heads/master)')
    self.assertMatches('ref/heads/beta', '(((heads/alpha)|(heads/beta))|(heads/gamma))|(heads/master)')
    self.assertMatches('ref/heads/gamma', '(((heads/alpha)|(heads/beta))|(heads/gamma))|(heads/master)')

    self.assertDoesNotMatch('ref/heads/delta', '(((heads/alpha)|(heads/beta))|(heads/gamma))|(heads/master)')


class TestTags(unittest.TestCase):
  def assertTagsForRef(self, ref, tags):
    prepared = PreparedBuild()
    prepared.tags_from_ref(ref, default_branch='master')
    self.assertEquals(set(tags), set(prepared._tags))

  def test_normal(self):
    self.assertTagsForRef('ref/heads/somebranch', ['somebranch'])
    self.assertTagsForRef('ref/heads/master', ['master', 'latest'])

    self.assertTagsForRef('ref/tags/somebranch', ['somebranch'])
    self.assertTagsForRef('ref/tags/master', ['master', 'latest'])

  def test_slash(self):
    self.assertTagsForRef('ref/heads/slash/branch', ['slash_branch'])
    self.assertTagsForRef('ref/tags/slash/tag', ['slash_tag'])

  def test_unusual(self):
    self.assertTagsForRef('ref/heads/foobar#2', ['foobar_2'])


class TestSkipBuild(unittest.TestCase):
  def testSkipNoMetadata(self):
    prepared = PreparedBuild()
    prepared.metadata = {}
    config = {}

    self.assertRaises(SkipRequestException, raise_if_skipped_build, prepared, config)

  def testSkipByBranchtagRegex(self):
    prepared = PreparedBuild()
    prepared.metadata = {
      'ref': 'ref/heads/master',
    }

    config = {
      'branchtag_regex': 'nothing'
    }
    self.assertRaises(SkipRequestException, raise_if_skipped_build, prepared, config)

  def testSkipByMessage(self):
    prepared = PreparedBuild()
    prepared.metadata = {
      'ref': 'ref/heads/master',
      'commit_info': {
        'message': '[skip build]',
      },
    }

    config = {}

    self.assertRaises(SkipRequestException, raise_if_skipped_build, prepared, config)


  def testDoesNotSkip(self):
    prepared = PreparedBuild()
    prepared.metadata = {
      'ref': 'ref/heads/master',
      'commit_info': {
        'message': 'some cool message',
      },
    }

    config = {
      'branchtag_regex': '(master)|(heads/master)',
    }

    raise_if_skipped_build(prepared, config)


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