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

import argparse
import datetime
import errno
import os
import re
import sys
import urllib.request
from http.server import HTTPServer, BaseHTTPRequestHandler


VERSION = "0.8"


def mkdir_p(path):
    try:
        os.makedirs(path)
    except OSError as exc:  # Python >2.5
        if exc.errno == errno.EEXIST and os.path.isdir(path):
            pass
        else:
            raise


def version(args):
    print(VERSION)
    sys.exit()


def server(args):
    from flask import Flask
    import socket

    app = Flask(__name__)

    @app.route("/")
    def handle_request():
        l = ""
        try:
            fn = os.path.join(args.path, "status")
            with open(fn) as f:
                d = f.read().strip()
        except:
            d = "Error reading file, try to run 'save' first"
        return d

    app.run(host="0.0.0.0", port=args.port)


def fetch_data(args):
    url = "http://" + str(args.host) + ":" + str(args.port)
    try:
        req = urllib.request.urlopen(url)
    except urllib.error.URLError:
        return None
    data = req.read().decode("utf-8")
    return data


def gui(args):
    import gi

    gi.require_version("Gtk", "3.0")
    from gi.repository import Gtk, GObject, GLib

    class Hello(Gtk.Dialog):
        def __init__(self):
            Gtk.Dialog.__init__(
                self, "Hello", None, 0, (Gtk.STOCK_OK, Gtk.ResponseType.OK)
            )

            self.set_default_response(Gtk.ResponseType.OK)
            self.set_size_request(700, 200)
            vbox = self.get_content_area()
            self.label = Gtk.Label()
            vbox.pack_start(self.label, True, True, 0)
            self.but = Gtk.Button(label="Refresh")
            vbox.pack_start(self.but, True, True, 0)
            hbox = Gtk.Box(spacing=6)
            vbox.pack_start(hbox, True, True, 0)
            self.entry = Gtk.Entry()
            hbox.pack_start(self.entry, True, True, 0)
            self.savebut = Gtk.Button(label="Save")
            hbox.pack_start(self.savebut, True, True, 0)
            self.but.connect("clicked", self.refresh_data)
            self.savebut.connect("clicked", self.save_data)
            self.refresh_data()

        def refresh_data(self, _=""):
            data = fetch_data(args)
            if data:
                self.label.set_text("Server returned: " + data)
                self.entry.set_text(data)
            else:
                self.label.set_text("Failed to fetch data, is the server up?")
                self.entry.set_text("")

        def save_data(self, _=""):
            contents = self.entry.get_text()
            try:
                mkdir_p(args.path)
                with open(os.path.join(args.path, "status"), "w") as f:
                    f.write(contents + "\n")
                print("File saved")
            except:
                print("Error saving file")
                raise

    h = Hello()
    h.show_all()
    h.present()
    response = h.run()


def cli(args):
    from prompt_toolkit import prompt

    c = ""
    while c != "exit":
        try:
            c = prompt("fetch | save <value> | delete | exit ? ")
            if c == "exit":
                sys.exit()
        except EOFError:
            sys.exit()
        if c == "fetch":
            data = fetch_data(args)
            if data:
                print("Server returned: " + data)
            else:
                print("Failed to fetch data, is the server up?")
        elif c == "delete":
            try:
                fn = os.path.join(args.path, "status")
                os.unlink(fn)
                print("File deleted at", fn)
            except:
                print("Error deleting file")
        elif re.match("save ", c):
            contents = c[5:]
            try:
                mkdir_p(args.path)
                fn = os.path.join(args.path, "status")
                with open(fn, "w") as f:
                    f.write(contents + "\n")
                print("File saved at", fn)
            except:
                print("Error saving file")
        else:
            print("What?")


# Looks like dead code?
class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global args
        print("Received request")
        self.send_response(200)
        self.end_headers()
        l = ""
        try:
            with open(os.path.join(args.path, "status")) as f:
                d = f.read().strip()
        except:
            d = "Error reading file"
        self.wfile.write(bytes(str(d), "utf-8"))


parser = argparse.ArgumentParser()
parser.add_argument("--verbose", "-v", action="count")
parser.add_argument("--port", "-p", type=int, help="port to use", default="8765")
parser.add_argument("--path", "-P", help="path to shared dir", default="/data")

subparsers = parser.add_subparsers(help="action to perform", dest="action")
subparsers.required = True
parser_server = subparsers.add_parser("server", help="run as server")
parser_server.set_defaults(func=server)
parser_gui = subparsers.add_parser("gui", help="GUI client")
parser_gui.add_argument("--host", help="server hostname", default="localhost")
parser_gui.set_defaults(func=gui)
parser_cli = subparsers.add_parser("cli", help="CLI client")
parser_cli.add_argument("--host", help="server hostname", default="localhost")
parser_cli.set_defaults(func=cli)
parser_version = subparsers.add_parser("version", help="print version")
parser_version.set_defaults(func=version)

args = parser.parse_args()
# print(args)
args.func(args)
