#! /usr/bin/env python3
#
# Copyright (C) 2018 Garmin Ltd.
#
# SPDX-License-Identifier: GPL-2.0-only
#

import os
import sys
import logging
import argparse
import sqlite3
import warnings

warnings.simplefilter("default")

sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), "lib"))

import hashserv

VERSION = "1.0.0"

DEFAULT_BIND = "unix://./hashserve.sock"


def main():
    parser = argparse.ArgumentParser(
        description="Hash Equivalence Reference Server. Version=%s" % VERSION,
        formatter_class=argparse.RawTextHelpFormatter,
        epilog="""
The bind address may take one of the following formats:
    unix://PATH         - Bind to unix domain socket at PATH
    ws://ADDRESS:PORT   - Bind to websocket on ADDRESS:PORT
    ADDRESS:PORT        - Bind to raw TCP socket on ADDRESS:PORT

To bind to all addresses, leave the ADDRESS empty, e.g. "--bind :8686" or
"--bind ws://:8686". To bind to a specific IPv6 address, enclose the address in
"[]", e.g. "--bind [::1]:8686" or "--bind ws://[::1]:8686"
        """,
    )

    parser.add_argument(
        "-b",
        "--bind",
        default=os.environ.get("HASHSERVER_BIND", DEFAULT_BIND),
        help='Bind address (default $HASHSERVER_BIND, "%(default)s")',
    )
    parser.add_argument(
        "-d",
        "--database",
        default=os.environ.get("HASHSERVER_DB", "./hashserv.db"),
        help='Database file (default $HASHSERVER_DB, "%(default)s")',
    )
    parser.add_argument(
        "-l",
        "--log",
        default=os.environ.get("HASHSERVER_LOG_LEVEL", "WARNING"),
        help='Set logging level (default $HASHSERVER_LOG_LEVEL, "%(default)s")',
    )
    parser.add_argument(
        "-u",
        "--upstream",
        default=os.environ.get("HASHSERVER_UPSTREAM", None),
        help="Upstream hashserv to pull hashes from ($HASHSERVER_UPSTREAM)",
    )
    parser.add_argument(
        "-r",
        "--read-only",
        action="store_true",
        help="Disallow write operations from clients ($HASHSERVER_READ_ONLY)",
    )

    args = parser.parse_args()

    logger = logging.getLogger("hashserv")

    level = getattr(logging, args.log.upper(), None)
    if not isinstance(level, int):
        raise ValueError("Invalid log level: %s" % args.log)

    logger.setLevel(level)
    console = logging.StreamHandler()
    console.setLevel(level)
    logger.addHandler(console)

    read_only = (os.environ.get("HASHSERVER_READ_ONLY", "0") == "1") or args.read_only

    server = hashserv.create_server(
        args.bind,
        args.database,
        upstream=args.upstream,
        read_only=read_only,
    )
    server.serve_forever()
    return 0


if __name__ == "__main__":
    try:
        ret = main()
    except Exception:
        ret = 1
        import traceback

        traceback.print_exc()
    sys.exit(ret)
