import os
import time
import threading
from io import BytesIO

from flask import Flask, request, make_response, abort, render_template
from flask_restful import Api, Resource

import base
import rest
import auth
from config import cfg

from sonic import Controller

app = Flask(__name__)
api = Api(app)


@app.route("/", methods=["POST"])
def default():
    token = request.form.get("token")
    if token == "": abort(401)
    print(token)
    if not auth.checktoken(token): abort(401)

    return render_template("apiinfo.html")
    

class SonicController(Resource):
    # open sensor connection
    def put(self):
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)
            
        if Controller.Open():
            return make_response('success')
        else:
            return make_response('open sensor connection failed', 500)

    # close sensor connection
    def delete(self): 
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)
            
        if Controller.Close():
            return make_response('success')
        else:
            return make_response('close sensor connection failed', 500)


class SonicMeasure(Resource):
    def post(self):
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)

        if not Controller.IsOpened() :
            return make_response('no sonic device connected', 500)

        d = Controller.Measure()
        
        if d > 0 :
            return make_response({"distance": d})
        else:
            return make_response('measure distance with sonic sensor failed', 500)


class SonicMeasures(Resource):
    def get(self):
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)
            
        d = Controller.GetDistance()
        if d > 0 :
            return make_response({"distance": d})
        else:
            return make_response('get measure distance from measure looping failed', 500)

        
    def put(self):
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)

        if not Controller.IsOpened() :
            return make_response('no sonic device connected', 500)

        reqjson = request.get_json()
        looptime = reqjson["looptime"]
        if looptime is None:
            return make_response('miss parameters', 400)
        if looptime <= 0.1:
            return make_response('parameters is illegal', 400)
        

        hr = Controller.MeasuresStart(looptime)
        if hr == 0 :
            return make_response("success")
        else:
            return make_response('start measure looping with sonic sensor failed', 500)

    
    def delete(self):
        token = request.headers.get('Authorization')
        if not auth.checktoken(token):
            return make_response('authorized failed', 401)

        if not Controller.IsOpened() :
            return make_response('no sonic device connected', 500)

        hr = Controller.MeasuresStop()
        if hr == 0 :
            return make_response("success")
        else:
            return make_response('stop measure looping with sonic sensor failed', 500)
        

api.add_resource(SonicController, '/sonic/controller')
api.add_resource(SonicMeasure, '/sonic/measure')
api.add_resource(SonicMeasures, '/sonic/measures')


if __name__ == '__main__':
    port = cfg.getint("server","port")
    
    app.run(
        host = '0.0.0.0',
        port = port,
        debug = False
    )