from datetime import datetime
from mock import Mock

from buildtrigger.gitlabhandler import GitLabBuildTrigger
from util.morecollections import AttrDict

def get_gitlab_trigger(subdir=''):
  trigger_obj = AttrDict(dict(auth_token='foobar', id='sometrigger'))
  trigger = GitLabBuildTrigger(trigger_obj, {
    'build_source': 'foo/bar',
    'subdir': subdir,
    'username': 'knownuser'
  })

  trigger._get_authorized_client = get_mock_gitlab
  return trigger

def adddeploykey_mock(project_id, name, public_key):
  return {'id': 'foo'}

def addprojecthook_mock(project_id, webhook_url, push=False):
  return {'id': 'foo'}

def get_currentuser_mock():
  return {
    'username': 'knownuser'
  }

def project(namespace, name):
  return {
    'id': '%s/%s' % (namespace, name),
    'default_branch': 'master',
    'namespace': {
      'id': namespace,
      'path': namespace,
      'name': namespace,
    },
    'path': name,
    'path_with_namespace': '%s/%s' % (namespace, name),
    'description': 'some %s repo' % name,
    'last_activity_at': str(datetime.utcfromtimestamp(0)),
    'web_url': 'https://bitbucket.org/%s/%s' % (namespace, name),
    'ssh_url_to_repo': 'git://%s/%s' % (namespace, name),
    'public': name != 'somerepo',
    'permissions': {
      'project_access': {
        'access_level': 50 if namespace == 'knownuser' else 0,
      }
    },
    'owner': {
      'avatar_url': 'avatarurl',
    }
  }

def getprojects_mock(page=1, per_page=100):
  return [
    project('knownuser', 'somerepo'),
    project('someorg', 'somerepo'),
    project('someorg', 'anotherrepo'),
  ]

def getproject_mock(project_name):
  if project_name == 'knownuser/somerepo':
    return project('knownuser', 'somerepo')

  if project_name == 'foo/bar':
    return project('foo', 'bar')

  return False


def getbranches_mock(project_id):
  return [
    {
      'name': 'master',
      'commit': {
        'id': 'aaaaaaa',
      }
    },
    {
      'name': 'otherbranch',
      'commit': {
        'id': 'aaaaaaa',
      }
    },
  ]

def getrepositorytags_mock(project_id):
  return [
    {
      'name': 'sometag',
      'commit': {
        'id': 'aaaaaaa',
      }
    },
    {
      'name': 'someothertag',
      'commit': {
        'id': 'aaaaaaa',
      }
    },
  ]

def getrepositorytree_mock(project_id, ref_name='master'):
  return [
    {'name': 'README'},
    {'name': 'Dockerfile'},
  ]

def getrepositorycommit_mock(project_id, commit_sha):
  if commit_sha != 'aaaaaaa':
    return False

  return {
    'id': 'aaaaaaa',
    'message': 'some message',
    'committed_date': 'now',
  }

def getusers_mock(search=None):
  if search == 'knownuser':
    return [
      {
        'username':  'knownuser',
        'avatar_url': 'avatarurl',
      }
    ]

  return False

def getbranch_mock(repo_id, branch):
  if branch != 'master' and branch != 'otherbranch':
    return False

  return {
    'name': branch,
    'commit': {
      'id': 'aaaaaaa',
    }
  }

def gettag_mock(repo_id, tag):
  if tag != 'sometag' and tag != 'someothertag':
    return False

  return {
    'name': tag,
    'commit': {
      'id': 'aaaaaaa',
    }
  }

def getrawfile_mock(repo_id, branch_name, path):
  if path == 'Dockerfile':
    return 'hello world'

  if path == 'somesubdir/Dockerfile':
    return 'hi universe'

  return False

def get_mock_gitlab():
  mock_gitlab = Mock()
  mock_gitlab.host = 'https://bitbucket.org'

  mock_gitlab.currentuser = Mock(side_effect=get_currentuser_mock)
  mock_gitlab.getusers = Mock(side_effect=getusers_mock)

  mock_gitlab.getprojects = Mock(side_effect=getprojects_mock)
  mock_gitlab.getproject = Mock(side_effect=getproject_mock)
  mock_gitlab.getbranches = Mock(side_effect=getbranches_mock)

  mock_gitlab.getbranch = Mock(side_effect=getbranch_mock)
  mock_gitlab.gettag = Mock(side_effect=gettag_mock)

  mock_gitlab.getrepositorytags = Mock(side_effect=getrepositorytags_mock)
  mock_gitlab.getrepositorytree = Mock(side_effect=getrepositorytree_mock)
  mock_gitlab.getrepositorycommit = Mock(side_effect=getrepositorycommit_mock)

  mock_gitlab.getrawfile = Mock(side_effect=getrawfile_mock)

  mock_gitlab.adddeploykey = Mock(side_effect=adddeploykey_mock)
  mock_gitlab.addprojecthook = Mock(side_effect=addprojecthook_mock)
  mock_gitlab.deletedeploykey = Mock(return_value=True)
  mock_gitlab.deleteprojecthook = Mock(return_value=True)
  return mock_gitlab