from flask import Blueprint, render_template, request, redirect, Response
import pydantic
import yaml

from conda_store import api, schema
from conda_store.server.utils import get_conda_store

app_ui = Blueprint('ui', __name__, template_folder='templates')


@app_ui.route('/create/', methods=['GET', 'POST'])
def ui_create_get_environment():
    if request.method == 'GET':
        return render_template('create.html')
    elif request.method == 'POST':
        try:
            specification_text = request.form.get('specification')
            conda_store = get_conda_store()
            specification = schema.CondaSpecification.parse_obj(
                yaml.safe_load(specification_text))
            api.post_specification(conda_store, specification.dict())
            return redirect('/')
        except yaml.YAMLError:
            return render_template('create.html', specification=specification_text, message='Unable to parse. Invalid YAML')
        except pydantic.ValidationError as e:
            return render_template('create.html', specification=specification_text, message=str(e))


@app_ui.route('/', methods=['GET'])
def ui_list_environments():
    conda_store = get_conda_store()
    return render_template('home.html',
                           environments=api.list_environments(conda_store.db),
                           metrics=api.get_metrics(conda_store.db))


@app_ui.route('/environment/<name>/', methods=['GET'])
def ui_get_environment(name):
    conda_store = get_conda_store()
    return render_template('environment.html',
                           environment=api.get_environment(conda_store.db, name),
                           environment_builds=api.get_environment_builds(conda_store.db, name))


@app_ui.route('/environment/<name>/edit/', methods=['GET'])
def ui_edit_environment(name):
    conda_store = get_conda_store()
    environment = api.get_environment(conda_store.db, name)
    specification = api.get_specification(conda_store.db, environment.specification.sha256)
    return render_template('create.html', specification=yaml.dump(specification.spec))


@app_ui.route('/specification/<sha256>/', methods=['GET'])
def ui_get_specification(sha256):
    conda_store = get_conda_store()
    specification = api.get_specification(conda_store.db, sha256)
    return render_template('specification.html', specification=specification, spec=yaml.dump(specification.spec))


@app_ui.route('/build/<build_id>/', methods=['GET'])
def ui_get_build(build_id):
    conda_store = get_conda_store()
    build = api.get_build(conda_store.db, build_id)
    return render_template('build.html', build=build)


@app_ui.route('/build/<build_id>/logs/', methods=['GET'])
def api_get_build_logs(build_id):
    conda_store = get_conda_store()
    log_key = api.get_build(conda_store.db, build_id).log_key
    return redirect(conda_store.storage.get_url(log_key))


@app_ui.route('/build/<build_id>/lockfile/', methods=['GET'])
def api_get_build_lockfile(build_id):
    conda_store = get_conda_store()
    lockfile = api.get_build_lockfile(conda_store.db, build_id)
    return Response(lockfile, mimetype='text/plain')


@app_ui.route('/build/<build_id>/archive/', methods=['GET'])
def api_get_build_archive(build_id):
    conda_store = get_conda_store()
    conda_pack_key = api.get_build(conda_store.db, build_id).conda_pack_key
    return redirect(conda_store.storage.get_url(conda_pack_key))
