from datetime import datetime
from mock import Mock

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

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

  trigger._get_authorized_client = get_mock_gitlab(with_nulls=False)
  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, is_org=False):
  project_access = None

  if name != 'null':
    if namespace == 'knownuser':
      project_access = {
        'access_level': 50,
      }
    else:
      project_access = {
        'access_level': 0,
      }

  data = {
    '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': project_access,
      'group_access': {'access_level': 0},
    },
    'owner': {
      'avatar_url': 'avatarurl',
    }
  }

  if name == 'null':
    del data['owner']['avatar_url']
    data['namespace']['avatar'] = None
  elif is_org:
    del data['owner']['avatar_url']
    data['namespace']['avatar'] = {'url': 'avatarurl'}

  return data

def getprojects_mock(with_nulls=False):
  if with_nulls:
    def _getprojs(page=1, per_page=100):
      return [
        project('someorg', 'null', is_org=True),
      ]
    return _getprojs

  else:
    def _getprojs(page=1, per_page=100):
      return [
        project('knownuser', 'somerepo'),
        project('someorg', 'somerepo', is_org=True),
        project('someorg', 'anotherrepo', is_org=True),
      ]
    return _getprojs

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

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

  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(with_nulls=False):
  def _get_mock():
    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(with_nulls))
    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

  return _get_mock