from data import model

import json

class BuildJobLoadException(Exception):
  """ Exception raised if a build job could not be instantiated for some reason. """
  pass

class BuildJob(object):
  """ Represents a single in-progress build job. """
  def __init__(self, job_item):
    self._job_item = job_item

    try:
      self._job_details = json.loads(job_item.body)
    except ValueError:
      raise BuildJobLoadException(
          'Could not parse build queue item config with ID %s' % self._job_details['build_uuid']
      )

    try:
      self._repo_build = model.get_repository_build(self._job_details['build_uuid'])
    except model.InvalidRepositoryBuildException:
      raise BuildJobLoadException(
          'Could not load repository build with ID %s' % self._job_details['build_uuid'])

    try:
      self._build_config = json.loads(self._repo_build.job_config)
    except ValueError:
      raise BuildJobLoadException(
          'Could not parse repository build job config with ID %s' % self._job_details['build_uuid']
      )

  def determine_cached_tag(self):
    """ Returns the tag to pull to prime the cache or None if none. """
    # TODO(jschorr): Change this to use the more complicated caching rules, once we have caching
    # be a pull of things besides the constructed tags.
    tags = self._build_config.get('docker_tags', ['latest'])
    existing_tags = model.list_repository_tags(self._repo_build.repository.namespace_user.username,
                                               self._repo_build.repository.name)

    cached_tags = set(tags) & set([tag.name for tag in existing_tags])
    if cached_tags:
      return list(cached_tags)[0]

    return None

  def job_item(self):
    """ Returns the job's queue item. """
    return self._job_item

  def repo_build(self):
    """ Returns the repository build DB row for the job. """
    return self._repo_build

  def build_config(self):
    """ Returns the parsed repository build config for the job. """
    return self._build_config
