#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import render_template, make_response, request
from flask_restx import Namespace, Resource

from .data_access_object import ObservationBlockObject as DAO
from .data_access_object import SetupObject as SAO

dao = DAO("/opt/tan/share/shins/saved")
tpl = SAO("/opt/tan/share/shins/templates/ob")

############################
# REST API
############################

api = Namespace('blocks', description='Observation blocks')

@api.route("/")
class BlockList(Resource):
    """Show and create OBs"""

    def get(self):
        """Show all observation OB files"""
        return dao.todos

    def post(self):
        """Create a new OB file based on name"""
        name = api.payload
        dao.create(name)
        return "", 204

    def delete(self):
        """Delete an OB file based on name"""
        name = api.payload
        dao.delete(name)
        return "", 204


@api.route("/<string:name>")
@api.param("name", "The uniqe name of the OB")
class Block(Resource):
    """Show a selected OB, update it, or add a new
    template in it.
    """

    def get(self, name):
        """Show a specific OB"""
        print("Show a specific OB")
        return dao.show(name)

    def put(self, name):
        """Update the OB"""
        data = api.payload
        #print(data)
        dao.update(name, data)
        return "", 204

    def post(self, name):
        """Add a template to the selected OB"""
        content = dao.content(name)
        #print(type(content))
        new_data = tpl.content(api.payload)
        # print(json.dumps(new_data, indent=4))
        data = content + new_data
        dao.update(name, data)
        return "", 204

    def delete(self, name):
        """Delete a template instance in the selected OB"""
        instance = api.payload
        data = dao.content(name)
        data.pop(instance)
        dao.update(name, data)
        return "", 204


############################
# WEB VIEW
############################
import json
from .data_access_object import SchemaObject as Sch
from .data_access_object import DocObject as Doc

web = Namespace('blocks', description='OB generator')


sch = Sch()
ref = SAO("/opt/tan/share/shins/templates/ref")
doc = Doc("/opt/tan/share/shins/templates/doc")

@web.route("/")
class BlockListWeb(Resource):
    """Show and create OBs"""

    def get(self):
        """Show all observation OB files"""
        print("show todos")
        data = sorted(dao.todos)

        return make_response(render_template("ob_list.html", data=data))



@web.route("/<string:name>")
@web.param("name", "The uniqe name of the OB")
class BlockWeb(Resource):
    """Show a selected OB, update it, or add a new
    template in it.
    """

    def get(self, name):
        """Show a specific OB"""
        included = request.args.get("included") or False

        ##################################################

        def fill_params(params_all, s, def_or_ref="def"):

            opts = { o["name"]: o for o in sch.read(s) } # dict

            if params_all and (s in params_all) and params_all[s]:
                 params = params_all[s]
            else:
                return []

            params_and_opts = []
            for k,v in params.items():
                for a,b in opts.items():
                    if a==k:
                        full_params = dict({"value":v, "type":def_or_ref}.items() + b.items())
                        print(json.dumps(full_params, indent=4))
                        params_and_opts.append(full_params)

            params_and_opts = sorted(params_and_opts, key=lambda k: k['name'])
            return params_and_opts

        ##################################################

        data = dao.show(name)
        #refs = ref.read(name)
        
        #print(json.dumps(data, indent=4))
        documentation = "No documentation"

        if data and "Template" in data and data["Template"]:
            for template in data["Template"]:
                defs_all = template
                refs_all = ref.read(template["TPLID"]) # takes the file
                documentation = doc.read(template["TPLID"])
                #print(json.dumps(defs_all, indent=4))
                #print(json.dumps(refs_all, indent=4))
                for subsystem in sch.schemas:
                    defs_filled = fill_params(defs_all, subsystem)
                    refs_filled = fill_params(refs_all, subsystem, def_or_ref="ref")
                    template[subsystem] = defs_filled + refs_filled
                    #print(json.dumps(defs_filled+refs_filled, indent=4))

        return make_response(render_template("ob.html",
                                             data=data, tpl=tpl.todos, doc=documentation,
                                             included=included))
