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

"""Websocket part"""

# System modules
import os
import time
from datetime import datetime
import json
from astropy.time import Time

# Third-party modules
from astropy.io import fits
import numpy as np

# Custom modules
from app import app
from util.master_listener_davide import thread
from util import variables as uvars
from util.mini_os import obsController

class Status:
    """store last status"""

    def __init__(self):
        self.last = {}

    def initial(self, socketio, names, client):
        socketio.sleep(1)
        for name in names:
            socketio.emit(name, self.last[name], room=client)

status = Status()


def to_seconds(date):
    return time.mktime(date.timetuple())

def send_timestamp(socketio, name):
    """send a unix timestamp"""

    while True:
        unix = to_seconds(datetime.utcnow())
        #print(unix)
        socketio.emit(name, unix)
        socketio.sleep(0.1)


def send_status(socketio, name, url, sleep=1, once=False):
    """send a json status (devices or rtc)"""

    # First time
    socketio.sleep(sleep)
    with app.test_client() as client:
        old = client.get(url).get_json()
    status.last[name] = old

    while not once:
        socketio.sleep(sleep)
        with app.test_client() as client:
            res = client.get(url).get_json()
            status.last[name] = res
            socketio.emit(name, res)
            # if res != old:
            #     socketio.emit(name, res)
            #     old = res


def tail_f(socketio, name, num_lines=30, sleep=0.25, once=False):
    """analogue of tail -f"""

    filename = "/data/log/log_of_python_test.log"
    file_size = os.path.getsize(filename)

    # First time
    with open(filename, 'r') as f:
        socketio.sleep(sleep)  # Sleep before checking again
        orig_lines = f.readlines()[-num_lines:]
        lines = [unicode(l) for l in orig_lines]
        # Initial lines on first page load
        socketio.emit(name, lines)
        status.last[name] = lines

    while not once:
        current_size = os.path.getsize(filename)
        if current_size < file_size:
            file_size = 0
        elif current_size > file_size:
            # File has been appended
            with open(filename, 'r') as f:
                f.seek(file_size)
                orig_lines = f.readlines()
                new_lines = [unicode(l) for l in orig_lines]
                file_size = current_size
                if new_lines:
                    socketio.emit(name, new_lines)
                    status.last[name] = new_lines
        socketio.sleep(sleep)  # Sleep before checking again


def send_cred(socketio, name):
    """send cred data in binary format"""

    while True:
        socketio.sleep(0.05)

        dtype = u"uint16"
        try:
            matrix = thread.img.astype(dtype)
        except:
            print("dummy")
            matrix = np.zeros(shape=(64,64)).astype(dtype)
        binary_data = matrix.tobytes()
        now = Time.now()
        data_bundle = {
            "shape": matrix.shape,
            "dtype": dtype,
            "data": binary_data,
            "timestamp": now.unix,
        }
        # print(matrix)
        socketio.emit(name, data_bundle)



#### prova
signs_list = []
with open(str(uvars.sign_map), "r") as f:
    for line in f:
        for x in line.split():
            signs_list.append(int(x))
signs = np.array(signs_list)
_, dmflat = obsController.getInternalSeqFloatVariable("RtcDmFlat")
flat = np.array(dmflat[0:97])
#####

def send_dm(socketio, name):
    """send dm data in binary format"""

    while True:
        socketio.sleep(0.05)
        dtype = u"float32"
        try:
            matrix = ((thread.shape * signs)-flat).astype(dtype)
        except:
            print("dummy")
            matrix = np.zeros(shape=(97)).astype(dtype)
        binary_data = matrix.tobytes()
        now = Time.now()
        data_bundle = {
            "shape": matrix.shape,
            "dtype": dtype,
            "data": binary_data,
            "timestamp": now.unix,
        }        
        #print(matrix)
        socketio.emit(name, data_bundle)


# def send_fits(socketio):
#     """download a fits"""

#     with fits.open("./temp.fits") as hdul:
#         matrix = hdul[0].data
#         header = hdul[0].header
#         unix = to_seconds(datetime.utcnow())
#         data_bundle = {
#             "shape": matrix.shape,
#             "dtype": matrix.dtype.name,
#             "data": matrix.tobytes(),
#             "header": [list(c) for c in header.cards],
#             "timestamp": unix,
#         }
#         socketio.emit('data_fits', data_bundle)
#         print((to_seconds(datetime.utcnow())-unix), "emitted")
#         print("bin {}".format(len(matrix)))
