#!/usr/bin/env python3

import argparse
import json
import os
import sys

from datetime import datetime
from pymongo import MongoClient


def _make_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument('--host', help="Hostname or ip for the mongo database",
                        **environ_or_required('MONGO_HOST'))
    parser.add_argument('--port', help="Port for the mongo database",
                        **environ_or_required('MONGO_PORT'))
    parser.add_argument('--db-name', help="Name for the database used to insert", required=True)
    parser.add_argument('--db-collection', help="Name for the collection used to insert", required=True)
    parser.add_argument('--metadata', help="Metadata to be included in the insert")
    parser.add_argument("value", help="value to insert in the mongodb")

    return parser


def environ_or_required(key):
    if os.environ.get(key):
        return {'default': os.environ.get(key)}
    else:
        return {'required': True}


def connect(host, port, db_name):
    client = MongoClient(host=host, port=int(port))
    if not db_name in client.list_database_names():
        print("report-mongodb: invalid db name, it does not exist in mongodb")
        sys.exit(1)
    return client[db_name]


def _get_json(value):
    try:
        return json.loads(value)
    except ValueError as e:
        return None


def insert(db, col, metadata, value):
    if not col in db.list_collection_names():
        print("report-mongodb: invalid db collection, it does not exist in db")
        sys.exit(1)

    json_value = _get_json(value)
    if not json_value:
        # This is an example of a correct value to be sent to mongodb
        # {
        #    "type": "info",
        #    "date": "2021-11-05",
        #    "time": "20:32:14",
        #    "info_type": "Error",
        #    "verb": "executing",
        #    "task": "google:ubuntu-18.04-64:tests/main/auto-refresh:parallel",
        #    "extra": null,
        #    "detail": {
        #        "lines": ["-----\n",
        #                  "snapd-state: expected a new auto-refresh change with id greater than 1, but it didn't happen\n",
        #                  "-----\n",
        #                  ".\n"]
        #    }
        # }
        print("report-mongodb: invalid value, it does not contain a valid json format")
        sys.exit(1)

    try:
        date = json_value["date"]
        time = json_value["time"]
        created_at = datetime.strptime("{} {}".format(date, time), "%Y-%m-%d %X").isoformat()
    except ValueError:
        created_at = datetime.now().isoformat("T", "seconds")

    json_value["created_at"] = created_at
    metadata_value = _get_json(metadata)
    json_value["metadata"] = metadata_value
    db[col].insert_one(json_value)
    print("report-mongodb: json value inserted in db")


def main():
    parser = _make_parser()
    args = parser.parse_args()

    if not args.host or not args.port:
        print("report-mongodb: host or port not specified")
        sys.exit(1)

    if not args.db_name or not args.db_collection:
        print("report-mongodb: db name or db collection not specified")
        sys.exit(1)

    if not args.value:
        print("report-mongodb: value cannot be empty")
        sys.exit(1)

    db = connect(args.host, args.port, args.db_name)
    insert(db, args.db_collection, args.metadata, args.value)


if __name__ == "__main__":
    main()
