
import logging
import json

from flask import abort, request, jsonify, make_response

from app import app
from util.names import parse_repository_name
from auth.auth import process_auth
from auth.permissions import (ReadRepositoryPermission,
                              ModifyRepositoryPermission)
from data import model


logger = logging.getLogger(__name__)


@app.route('/v1/repositories/<path:repository>/tags',
           methods=['GET'])
@process_auth
@parse_repository_name
def get_tags(namespace, repository):
  permission = ReadRepositoryPermission(namespace, repository)

  if permission.can() or model.repository_is_public(namespace, repository):
    tags = model.list_repository_tags(namespace, repository)
    tag_map = {tag.name: tag.image.docker_image_id for tag in tags}
    return jsonify(tag_map)

  abort(403)


@app.route('/v1/repositories/<path:repository>/tags/<tag>',
           methods=['GET'])
@process_auth
@parse_repository_name
def get_tag(namespace, repository, tag):
  permission = ReadRepositoryPermission(namespace, repository)

  if permission.can() or model.repository_is_public(namespace, repository):
    tag_image = model.get_tag_image(namespace, repository, tag)
    resp = make_response('"%s"' % tag_image.docker_image_id)
    resp.headers['Content-Type'] = 'application/json'
    return resp

  abort(403)


@app.route('/v1/repositories/<path:repository>/tags/<tag>',
           methods=['PUT'])
@process_auth
@parse_repository_name
def put_tag(namespace, repository, tag):
  permission = ModifyRepositoryPermission(namespace, repository)

  if permission.can():
    docker_image_id = json.loads(request.data)
    model.create_or_update_tag(namespace, repository, tag, docker_image_id)

    return make_response('Created', 200)

  abort(403)


@app.route('/v1/repositories/<path:repository>/tags/<tag>',
           methods=['DELETE'])
@process_auth
@parse_repository_name
def delete_tag(namespace, repository, tag):
  permission = ModifyRepositoryPermission(namespace, repository)

  if permission.can():
    model.delete_tag(namespace, repository, tag)

    return make_response('Deleted', 204)

  abort(403)


@app.route('/v1/repositories/<path:repository>/tags',
           methods=['DELETE'])
@process_auth
@parse_repository_name
def delete_repository_tags(namespace, repository):
  permission = ModifyRepositoryPermission(namespace, repository)

  if permission.can():
    model.delete_all_repository_tags(namespace, repository)

    return make_response('Deleted', 204)

  abort(403)
