import json
import time
import traceback

from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn

from . import api
from . import db

class BlenderfarmHTTPServerRequestHandler(BaseHTTPRequestHandler):
    def send_text(self, text_data):
        self.wfile.write(bytes(text_data, 'utf8'))

    def send_json(self, json_data):
        self.send_text(json.dumps(json_data))

    def respond_json(self, json_data, status=200):
        self.send_response(status)
        self.send_header('Content-type', 'application/json')
        self.end_headers()

        self.send_json(json_data)

        return

    def respond_error(self, status):
        self.send_response(status)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()

        self.send_text(str(status))

        return

    def detect_api_version(self, path):
        path = self.path.split('/')[1:]

        if len(path) >= 1:
            return [path[0], '/'.join(path[1:])]

        return [None, '/'.join(path)]
    def do_method(self, method):
        try:

            api_version, path = self.detect_api_version(self.path)
            if not api_version:
                print('No API version present in path "' + self.path + '"')
                self.respond_error(400)
                return
            if api_version not in self.api_handlers:
                print('No such API version "' + api_version + '" (path: "' + self.path + '")!')
                self.respond_error(400)
                return

            api_handler = self.api_handlers[api_version]
            route_handler = api_handler.get_route(method, path)
            if not route_handler:
                self.respond_error(500)
                return
            route_handler(self, self)
            
        except Exception as _: # pylint: disable=broad-except
            print('Exception during "do_' + method + '":')
            traceback.print_exc()
            self.respond_error(500)
    def do_GET(self):
        self.do_method('GET')
    def do_POST(self):
        self.do_method('POST')

    def log_message(self, _format, *args):
        _ = _format, args
        
        return


#from . import api_v1

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
class Server:
    def __init__(self, host='localhost', port=44363):
        self.host = host
        self.port = port

        self.jobs = []

        self.init_api_handlers()
        self.init_server()

        self.users = db.Users()

        self.start_time = time.monotonic()

    def get_uptime(self):
        return time.monotonic() - self.start_time

    def init_api_handlers(self):
        self.api_handlers = {}

        v1 = api.v1.Server(self).init() # pylint: disable=invalid-name
        
        self.api_handlers['v1'] = v1

    def init_server(self):
        request_handler = BlenderfarmHTTPServerRequestHandler
        request_handler.server = self

        request_handler.api_handlers = {
            'v1': self.api_handlers['v1']
        }

        self.httpd = ThreadedHTTPServer((self.host, self.port), request_handler)

        #self.api_v1 = api_v1.API(self).init()

    def start(self):
        self.httpd.serve_forever()

    def get_next_task(self, parameters):
        pass