#! /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
from hashserv.server import DEFAULT_ANON_PERMS

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"

Note that the default Anonymous permissions are designed to not break existing
server instances when upgrading, but are not particularly secure defaults. If
you want to use authentication, it is recommended that you use "--anon-perms
@read" to only give anonymous users read access, or "--anon-perms @none" to
give un-authenticated users no access at all.

Setting "--anon-perms @all" or "--anon-perms @user-admin" is not allowed, since
this would allow anonymous users to manage all users accounts, which is a bad
idea.

If you are using user authentication, you should run your server in websockets
mode with an SSL terminating load balancer in front of it (as this server does
not implement SSL). Otherwise all usernames and passwords will be transmitted
in the clear. When configured this way, clients can connect using a secure
websocket, as in "wss://SERVER:PORT"

The following permissions are supported by the server:

    @none       - No permissions
    @read       - The ability to read equivalent hashes from the server
    @report     - The ability to report equivalent hashes to the server
    @db-admin   - Manage the hash database(s). This includes cleaning the
                  database, removing hashes, etc.
    @user-admin - The ability to manage user accounts. This includes, creating
                  users, deleting users, resetting login tokens, and assigning
                  permissions.
    @all        - All possible permissions, including any that may be added
                  in the future
        """,
    )

    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)",
    )
    parser.add_argument(
        "--db-username",
        default=os.environ.get("HASHSERVER_DB_USERNAME", None),
        help="Database username ($HASHSERVER_DB_USERNAME)",
    )
    parser.add_argument(
        "--db-password",
        default=os.environ.get("HASHSERVER_DB_PASSWORD", None),
        help="Database password ($HASHSERVER_DB_PASSWORD)",
    )
    parser.add_argument(
        "--anon-perms",
        metavar="PERM[,PERM[,...]]",
        default=os.environ.get("HASHSERVER_ANON_PERMS", ",".join(DEFAULT_ANON_PERMS)),
        help='Permissions to give anonymous users (default $HASHSERVER_ANON_PERMS, "%(default)s")',
    )
    parser.add_argument(
        "--admin-user",
        default=os.environ.get("HASHSERVER_ADMIN_USER", None),
        help="Create default admin user with name ADMIN_USER ($HASHSERVER_ADMIN_USER)",
    )
    parser.add_argument(
        "--admin-password",
        default=os.environ.get("HASHSERVER_ADMIN_PASSWORD", None),
        help="Create default admin user with password ADMIN_PASSWORD ($HASHSERVER_ADMIN_PASSWORD)",
    )

    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 (Try ERROR/WARNING/INFO/DEBUG)" % 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
    if "," in args.anon_perms:
        anon_perms = args.anon_perms.split(",")
    else:
        anon_perms = args.anon_perms.split()

    server = hashserv.create_server(
        args.bind,
        args.database,
        upstream=args.upstream,
        read_only=read_only,
        db_username=args.db_username,
        db_password=args.db_password,
        anon_perms=anon_perms,
        admin_username=args.admin_user,
        admin_password=args.admin_password,
    )
    server.serve_forever()
    return 0


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

        traceback.print_exc()
    sys.exit(ret)
