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

# System modules
import html
import time
import subprocess
from flask import Response
from flask import render_template, make_response, request
from flask_restx import Namespace, Resource, fields
from astropy.time import Time

# Custom modules
from .data_access_object import ObservationBlockObject as DAO
from sequencer import Sequencer

dao = DAO("ob")

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

api = Namespace('sequencer', description='Sequencer')

# import logging
# api.logger.disabled = True
# log = logging.getLogger('werkzeug')
# log.disabled = True
# # log = logging.getLogger('SHINS')
# # log.disabled = True

# # New, 2022 Method:
# logging.getLogger('werkzeug').disabled = True

list_of_ob = api.model('list', {
    'id': fields.Integer(readonly=True, description='The OB unique identifier'),
    'name': fields.String(required=True, description='The OB name')
})


@api.route("/")
class BobList(Resource):
    """Show and modify a list of OBs to be sequenced"""

    @api.doc('list_ob')
    @api.marshal_list_with(list_of_ob)
    def get(self):
        """Show all OB in the sequence"""
        return dao.todos

    @api.doc('add_ob')
    @api.expect(list_of_ob)
    @api.marshal_with(list_of_ob, code=201)
    def post(self):
        """Add a new OB to the sequence"""
        data = api.payload


@api.route('/<int:id>')
@api.response(404, 'OB not found')
@api.param('id', 'The OB identifier')
class Bob(Resource):
    '''Let delete a specific OB'''

    @api.doc('delete_ob')
    @api.response(204, 'OB deleted')
    def delete(self, id):
        '''Delete an OB given its identifier'''
        dao.delete(id)
        return '', 204


@api.route("/run")
class BobRun(Resource):
    """Manage the sequencer"""

    seq = Sequencer()

    def get(self, seq=seq):
        """Show the sequencer status"""

        res = {
            "response": {
                "name": seq.tpl.name if seq.tpl else None,
                "paused": seq.tpl.paused if seq.tpl else None,
                "quitting": self.tpl.aborted if seq.tpl else None,
                "error": self.tpl.error if seq.tpl else None,
            },
            "error": seq.error,
        }
        return res

    def put(self, seq=seq):
        """Pause or resume the template execution. Inverting the logic with
        respect to sequencer class:
        PUT /sequencer/run true: resume,
        PUT /sequencer/run false: pause
        """
        in_execution = api.payload
        seq.resume() if in_execution else seq.pause()
        res = {
            "response": seq.tpl.paused,
            "error": seq.error,
        }
        return res

    def post(self, seq=seq):
        """Start the sequencer"""
        name = api.payload
        if name:
            filename = dao.show(name)["filename"]
            seq.load_file(filename)
            seq.execute()
            res = {
                "response": seq.ob,
                "error": seq.error,
            }
        else:
            res = {
                "response": None,
                "error": ["No OB"],
            }
        return res

    def delete(self, seq=seq):
        """Stop the sequencer"""
        seq.quit()
        #res = "None"
        if seq.ob:
            res = {
                "response": seq.ob if seq.ob else None,
                "error": seq.error,
            }
        return res


############################
# WEB VIEW
############################

web = Namespace('sequencer', description='Web Sequencer interface')


@web.route("/")
class BobWeb(Resource):

    def get(self):
        data = dao.todos
        today = Time.now().iso.split()[0]
        print(f"tail -f -n30  ./data/log/OARPAF.{today}.log")
        return make_response(render_template("sequencer.html", data=data))


@web.route('/stream')
class Stream(Resource):
    def get(self):
        def inner():
            try:
                today = Time.now().iso.split()[0]

                proc = subprocess.Popen(
                    [f"tail -f -n30 ./data/log/OARPAF.{today}.log"],
                    shell=True,
                    stdout=subprocess.PIPE
                )

                for line in iter(proc.stdout.readline, ''):
                    line = line.rstrip().decode()
                    #line = html.escape(line)
                    time.sleep(0.05)
                    yield 'data: {}\n\n'.format(line)
                    # yield line.rstrip().decode() + '<br/>\n'

            except GeneratorExit as e:
                print(e)
                print("Closing subprocess")
                proc.terminate()
                proc.wait()
                print("Subprocess closed")

        print("Streaming template log...")
        return Response(inner(), mimetype="text/event-stream")
