from flask import jsonify, request, Response, json, g
from orlo.app import app
from orlo import queries
from orlo.config import config
from orlo.exceptions import InvalidUsage
from orlo.user_auth import token_auth
from orlo.orm import db, Release, Package, PackageResult, ReleaseNote, \
    ReleaseMetadata, Platform
from orlo.util import validate_request_json, create_release, \
    validate_release_input, validate_package_input, fetch_release, \
    create_package, fetch_package, stream_json_list, str_to_bool, is_uuid
from orlo.user_auth import conditional_auth

security_enabled = config.getboolean('security', 'enabled')


@app.route('/releases', methods=['POST'])
@conditional_auth(conditional_auth(token_auth.token_required))
def post_releases():
    """
    Create a release - the first step in a deployment

    :<json string user: User that is performing the release
    :<json string team: The development team responsible for this release
    :<json array platforms: List of platforms receiving the release
    :<json array references: List of external references, e.g. Jira ticket
    :>json string id: UUID reference to the created release
    :reqheader Content-Type: Must be application/json
    :status 200: Release was created successfully
    :status 400: Invalid request

    **Example curl**:

    .. sourcecode:: shell

        curl -H "Content-Type: application/json" \\
        -X POST \\
        http://127.0.0.1/releases \\
        -d '{"note": "blah", "platforms": ["site1"], "references": ["ticket"],
        "team": "A-Team", "user": "aforbes"}'
    """
    validate_release_input(request)
    release = create_release(request)

    if request.json.get('note'):
        release_note = ReleaseNote(release.id, request.json.get('note'))
        db.session.add(release_note)

    if request.json.get('metadata'):
        for key, value in request.json.get('metadata').items():
            metadata = ReleaseMetadata(release.id, key, value)
            db.session.add(metadata)

    app.logger.info(
        'Create release {}, references: {}, platforms: {}'.format(
            release.id, release.notes, release.references, release.platforms,
            release.metadata)
    )

    release.start()

    db.session.add(release)
    db.session.commit()

    return jsonify(id=release.id)


@app.route('/releases/<release_id>/packages', methods=['POST'])
@conditional_auth(token_auth.token_required)
def post_packages(release_id):
    """
    Add a package to a release

    :param string release_id: UUID of the release to add the package to
    :<json string name: Name of the package
    :<json string version: Version of the package
    :<json boolean rollback: Whether this package deploy is a rollback
    :>json string id: UUID reference to the created package
    :reqheader Content-Type: Must be application/json
    :status 200: Package was added to the release successfully
    :status 400: Invalid request
    **Example curl**:

    .. sourcecode:: shell

        curl -H "Content-Type: application/json" \\
        -X POST http://127.0.0.1/releases/${RELEASE_ID}/packages \\
        -d '{"name": "test-package", "version": "1.0.1"}'
    """
    validate_package_input(request, release_id)