# -*- mode: Python;-*-

from pprint import pprint as pp
import ipaddress
import json
import os

class MongoHms:
    """Connect to Mongo database and provide methods to control HMS."""
    import pymongo

    def __init__(self):
        self.myclient = self.pymongo.MongoClient(
            "mongodb://"
            + "admin"
            + ":" + os.getenv("HMS_MONGO_PASSWORD")
            + "@" + ",".join(["hms01-mr.intr:27017",
                              "hms02-mr.intr:27017",
                              "hms03-mr.intr:27017"])
            + "/admin?replicaSet=hms-rs0"
        )
        self.service = self.myclient["staffResourceController"]["service"]
        self.socket = self.myclient["staffResourceController"]["socket"]
        self.service_socket = self.myclient["staffResourceController"]["serviceSocket"]
        self.installer = self.myclient["appscat"]["installer"]

    def ip_address_to_int(self, ip_address):
        """Convert IP address to integer."""
        return int(ipaddress.ip_address(ip_address))

    def web_find_socket(self, socket_name, server):
        """Return socket by SOCKET_NAME on SERVER."""
        return [socket for socket in self.socket.find({"name": socket_name + "@" + server})]

    def web_socket_id(self, socket_name, server):
        """Return socket_id by SOCKET_NAME on SERVER."""
        return str(self.web_find_socket(socket_name, server)[0]["_id"])

    def web_create_socket(self, socket_name, ip_address, protocol, server, port):
        """Create socket with specified SOCKET_NAME, IP_ADDRESS, PROTOCOL on SERVER PORT."""
        if not self.web_find_socket(socket_name, server):
            self.socket.insert_one({"protocol": protocol,
                                    "address": self.ip_address_to_int(ip_address),
                                    "port": port,
                                    "name": socket_name + "@" + server,
                                    "switchedOn": True,
                                    "_class" : "NetworkSocket"}).inserted_id
        return self.web_socket_id(socket_name, server)

    def web_service_name_to_server_id(self, service_name, server):
        """Return server id from SERVICE_NAME on SERVER."""
        return self.service.find_one({"name": service_name + "@" + server})['serverId']

    def web_find_service(self, service_name, server):
        """Return list of services matching SERVICE_NAME on SERVER."""
        return [service for service in self.service.find({"name": service_name + "@" + server})]

    def web_service_id(self, service_name, server):
        """Return service id from SERVICE_NAME on SERVER."""
        return str(self.web_find_service(service_name, server)[0]["_id"])

    def web_create_service(self, service_name, template_id, server, server_id, socket):
        """Create service with specified SERVICE_NAME, TEMPLATE_ID on SERVER with SERVER_ID on SOCKET."""
        if not self.web_find_service(service_name, server):
            self.service.insert_one({
                "serverId": server_id,
                "templateId": template_id,
                "socketIds": [socket],
                "instanceProps": {
                    "security_level": "default"
                },
                "name": service_name + "@" + server,
                "switchedOn": True,
                "_class": "ru.majordomo.hms.rc.staff.resources.Service"
        })
        return self.web_service_id(service_name, server)

    def web_create_ssh_service(self, server, ip_address):
        """Create ssh service on SERVER with IP_ADDRESS."""
        return self.web_create_service(
            "ssh-guest-room",
            "5d6693a6f7619300012fbbd5",
            "5d8a2a2e708301660013776d",
            server,
            self.web_service_name_to_server_id('nginx', server),
            self.web_create_socket("ssh-guest-room-ssh", ip_address, "ssh", server, "1022")
        )

    def web_create_php_service(self, template_id, version, server, ip_address, port):
        """Create php service with specified TEMPLATE_ID with php VERSION on SERVER with IP_ADDRESS on PORT."""
        service = "apache2-php" + version + "-default"
        return self.web_create_service(
            service,
            template_id,
            server,
            self.web_service_name_to_server_id("nginx", server),
            self.web_create_socket(service + "-http", ip_address, "http", server, port),
        )

    def task_set_error(self, account_id):
        """Set all running task on ACCOUNT_ID (e.g. "208112") as processed."""
        return self.myclient["personmgr"]["processingBusinessOperation"].update_many({
            "personalAccountId":account_id,
            "state":"PROCESSING"
        }, {"$set": {"state":"ERROR"}})

    def task_set_processed(self, account_id):
        """Set all running task on ACCOUNT_ID (e.g. "208112") as processed."""
        return self.myclient["personmgr"]["processingBusinessOperation"].update_many({
            "personalAccountId":account_id,
            "state":"PROCESSING"
        }, {"$set": {"state":"PROCESSED"}})

    def wordpress(self, version):
        from datetime import datetime
        current_time = datetime.utcnow()
        self.installer.insert_one({
            "name" : f"WordPress {version} Installer",
            "dockerImage" : f"docker-registry.intr/apps/wordpress:{version}",
            "requiredParams" : [
                "DB_HOST",
                "APP_PATH",
                "APP_TITLE",
                "DB_NAME",
                "ADMIN_USERNAME",
                "DB_PASSWORD",
                "DB_USER",
                "ADMIN_EMAIL",
                "ADMIN_PASSWORD",
                "DOMAIN_NAME"
            ],
            "created" : current_time,
            "updated" : current_time,
            "_class" : "ru.majordomo.hms.appscat.model.Installer"
        })

