#!/usr/bin/env python3.5
# Copyright 2017 Digital
#
# This file is part of BeeWatch.
#
# BeeWatch is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BeeWatch is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BeeWatch.  If not, see <http://www.gnu.org/licenses/>.
#

import argparse
import gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
import logging
import logging.config
import logging.handlers
import sys
import mylibnetwork
import threading
import socket
import traceback
import time
import yaml

import beewatch
# import beewatch.server as beeserver
import beewatch.server

parser = argparse.ArgumentParser(
    # usage="use this to play",
    description="BeeWatch Server",
)

parser.add_argument(
    "host",
    type=str,
    help="hostname/ip address/filename (only if --use-file was specified)"
)
parser.add_argument(
    "port",
    type=int,
    default=80540,
    nargs="?",
    help="the port on wich the connection will open up. ignored if --use-file \
        is given"
)
parser.add_argument(
    "-d","--debug",
    default=False,
    action="store_true",
    help="enables logging"
)
group_af_family = parser.add_mutually_exclusive_group()
group_af_family.add_argument(
    "-u","--af-unix",
    dest="af_family",
    # default=False,
    action="store_const",
    const="AF_UNIX",
    help="""use an AF_UNIX socket (a file). can't be used in combination with
        --af-inet."""
    # " will be used \
    #     instead of an AF_INET socket (hostname/ip address + port)."
)
group_af_family.add_argument(
    "-i","--af_inet",
    default="AF_INET",
    dest="af_family",
    action="store_const",
    const="AF_INET",
    help="""use an AF_INET socket (hostname/ip address + port). can't be used
        with --af-unix"""
        # (hostname/ip address + port) will be used instead of an AF_INET \
        # socket (a file)."
)

args = parser.parse_args()
print(args)
if args.debug:
    with open("config/logging.yaml") as f:
        data = f.read()
    config = yaml.safe_load(data)
    logging.config.dictConfig(config)

if args.af_family == "AF_UNIX":
    port = None
elif args.af_family == "AF_INET":
    port = args.port

bee_server = beewatch.server.BeeWatchServer(
    host=args.host,
    port=args.port,
    af_family=args.af_family,
)
# bee_api = beeserver.BeeAPI()

# s = mylibnetwork.Server(
#     host=args.host,
#     port=port,
#     handler=beeserver.ConnHandlerBeeWatch,
#     handler_kwargs={"bee_api":bee_api}
#     )

bee_server.run()
try:
    while True:
        try:
            if bee_server.is_alive():
                bee_server.join(1)
            else:
                break
        except Exception as e:
            log.warn("an error occured, aborting")
            log.error(e, exc_info=True)
            bee_server.stop()
            break
except KeyboardInterrupt:
    print("\r    ", end="\r")
    logging.warn("keyboardinterrupt! aborting!")
    bee_server.stop()




sys.exit()

log = logging.getLogger(__name__+".server")
logc = logging.getLogger(__name__+".chat")

Notify.init("Bee Watch Server")
#
# class ConnHandlerBeeWatch(mylibnetwork.ConnHandlerBase):
#     def __init__(self, socket, addr, server, action=None):
#         self.status = "init"
#         self.super_class = super(ConnHandlerBeeWatch, self)
#         self.super_class.__init__(socket, addr, server)
#         logc.info('hey')
#         self.server = server
#         self.address = addr
#         self.action=action
#         self.command_to_function={
#             "set_speed":self.action.c.movement_control.set_speed,
#             "mod_speed":self.action.c.movement_control.change_speed,
#             "get_speed":self.speedcheck,
#             "print":self.echo,
#             "None":None,
#         }
#     def welcome_client(self):
#         self.send("this is the server speaking, hello new client!")
#     def handle(self, data_decoded):
#         data_decoded=data_decoded.strip()
#         logc.info("Client:"+data_decoded)
#         if data_decoded.find(" ") != -1:
#             cmd=data_decoded.split()[0]
#             args=data_decoded.split()[1:]
#         else:
#             cmd=data_decoded
#             args=()
#             kwargs={}
#         if cmd in self.command_to_function.keys():
#             try:
#                 # self.respond(str(args))
#                 self.command_to_function[cmd](respond_method=self.respond,*args)
#             except:
#                 tb = traceback.format_exc()
#                 print(tb)
#                 self.respond(tb)
#                 # for line in tb.split('\n'):
#                 #     self.respond(line)
#                 #     # print(line)
#                 #     # time.sleep(0.001)
#                 #     time.sleep(0.1)
#                 #     # if line != "\n"
#         else:
#             self.respond("Unknown command")
#         # Notify.Notification.new(
#         #     self.address[0]+" ("+self.server.host+":"+str(self.server.port)+")",
#         #     data_decoded
#         #     ).show()
#     def echo(self,*args,**kwargs):
#         logc.info(str(args))
#         logc.info(str(kwargs))
#     def speedcheck(self,respond_method):
#         left_speed=str(self.action.c.movement_control.get_speed("left"))
#         right_speed=str(self.action.c.movement_control.get_speed("right"))
#         result = "left: "+left_speed+", right: "+right_speed
#         logc.info(result)
#         self.respond(result)
#     def respond(self,text,*args):
#         self.send(text)
#
# # logging.basicConfig(
# #         format = myLogger.fmt + " {process:^^20}",
# #         datefmt = myLogger.datefmt,
# #         style = "{",
# #         level = logging.DEBUG,
# #         handlers = [
# #             myLogger.logHandler_console,
# #         ]
# #     )
# # logger_server = logging.getLogger("server")
# # logger_server.propagate = False
# # logHandler_server_file = logging.handlers.WatchedFileHandler(filename="logs/server.log")
# # logHandler_server_file.setFormatter(myLogger.logFormatter)
# # logHandler_server_file.setLevel(level=logging.DEBUG)
# # logger_server.addHandler(myLogger.logHandler_console)
# # logger_server.addHandler(logHandler_server_file)
# # logger_beewatch = logging.getLogger("BeeWatch")
# # logger_beewatch.propagate = False
# # logHandler_beewatch_file = logging.handlers.WatchedFileHandler(filename="logs/beeserver.log")
# # logHandler_beewatch_file.setFormatter(myLogger.logFormatter)
# # logHandler_beewatch_file.setLevel(level=logging.DEBUG)
# # logger_beewatch.addHandler(myLogger.logHandler_console)
# # logger_beewatch.addHandler(logHandler_beewatch_file)
#
#
# action=beeserver.BoatAction()
# boat_movement=beeserver.BoatMovement(action.boat_api)
# action.add_component("movement_control",boat_movement)
# # engine_left=beeserver.Engine(logger_beewatch,action,{"name":"engine_left"})
# # engine_right=beeserver.Engine(logger_beewatch,action,{"name":"engine_right"})
# # action.add_component("engine_left",engine_left)
# # action.add_component("engine_right",engine_right)
# argv_dict = dict(zip(range(0,len(sys.argv)),sys.argv))
# port = argv_dict.get(2,None)
# if port != None:
#     port = int(port)
# s = mylibnetwork.Server(
#     host=sys.argv[1],
#     port=port,
#     handler=ConnHandlerBeeWatch,
#     handler_kwargs={"action":action}
#     )
# bee_server.run()
# while True:
#     try:
#         # print("".join(myLogger.list_stream))
#         if bee_server.is_alive():
#             bee_server.join(1)
#         else:
#             break
#     except KeyboardInterrupt:
#         print("\r    ", end="\r")
#         logging.warn("keyboardinterrupt! aborting!")
#         bee_server.stop()
#         break
#     except Exception as e:
#         log.warn("an error occured, aborting")
#         log.error(e, exc_info=True)
#         bee_server.stop()
#         break