import json

from manifest_models_interface import ManifestLabel, ManifestLabelInterface, ManifestAndImage
from data import model
from image_models_pre_oci import pre_oci_model as image_models


class ManifestLabelPreOCI(ManifestLabelInterface):
  def get_manifest_labels(self, namespace_name, repository_name, manifestref, filter=None):
    try:
      tag_manifest = model.tag.load_manifest_by_digest(namespace_name, repository_name, manifestref)
    except model.DataModelException:
      return None

    labels = model.label.list_manifest_labels(tag_manifest, prefix_filter=filter)
    return [self._label(l) for l in labels]

  def create_manifest_label(self, namespace_name, repository_name, manifestref, key, value, source_type_name, media_type_name):
    try:
      tag_manifest = model.tag.load_manifest_by_digest(namespace_name, repository_name, manifestref)
    except model.DataModelException:
      return None

    return self._label(model.label.create_manifest_label(tag_manifest, key, value, source_type_name, media_type_name))
  
  def get_manifest_label(self, namespace_name, repository_name, manifestref, label_uuid):
    try:
      tag_manifest = model.tag.load_manifest_by_digest(namespace_name, repository_name, manifestref)
    except model.DataModelException:
      return None

    return self._label(model.label.get_manifest_label(label_uuid, tag_manifest))

  def delete_manifest_label(self, namespace_name, repository_name, manifestref, label_uuid):
    try:
      tag_manifest = model.tag.load_manifest_by_digest(namespace_name, repository_name, manifestref)
    except model.DataModelException:
      return None

    return self._label(model.label.delete_manifest_label(label_uuid, tag_manifest))
  
  def get_repository_manifest(self, namespace_name, repository_name, digest):
    try:
      tag_manifest = model.tag.load_manifest_by_digest(namespace_name, repository_name, digest)
    except model.DataModelException:
      return None

    # TODO: remove this dependency on image once we've moved to the new data model.
    image = image_models.get_repository_image(namespace_name, repository_name,
                                              tag_manifest.tag.image.docker_image_id)

    manifest_data = json.loads(tag_manifest.json_data)
    return ManifestAndImage(digest=digest, manifest_data=manifest_data, image=image)


  def _label(self, label_obj):
    if not label_obj:
      return None
    return ManifestLabel(
      uuid=label_obj.uuid,
      key=label_obj.key,
      value=label_obj.value,
      source_type_name=label_obj.source_type.name,
      media_type_name=label_obj.media_type.name,
    )

pre_oci_model = ManifestLabelPreOCI()