# -*- coding: utf-8 -*-
import logging
import random

from sqlalchemy import text

from website import errors
from website import settings
from website.db.enterprise_device.enterprise_device import EnterpriseEntityRepository as EntRepo
from website.db_mysql import to_json_list, to_json
from website.handler import APIHandler, authenticated, operation_log
from website.util import aes
from website.util import shortuuid


class AddHandler(APIHandler):
    """
    - 描述:新建服务器
    - 请求方式:post
    - 请求参数:
    > - entity_id, int, 企业id
    > - name, string, 服务器名称
    > - ip, string,
    > - port, int, 默认端口
    > - username, string, 用户名
    > - passwd, string,

    - 返回值:无
    """

    @authenticated
    @operation_log("企业项目", "服务器管理", "新建", "新建服务器", "")
    def post(self):
        entity_id = self.get_int_argument('entity_id')
        name = self.get_escaped_argument('name', '')
        ip = self.get_escaped_argument('ip', '')
        port = self.get_int_argument("port", 22)
        username = self.get_escaped_argument('username', '')
        passwd = self.get_escaped_argument('passwd', '')

        if not entity_id:
            raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity_id is required")
        e = EntRepo()
        entity_suid = e.get_entity_suid(entity_id)
        if not entity_suid:
            raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity is invalid")

        with self.app_mysql.connect() as conn:
            conn.execute(
                text(
                    "insert into "
                    "enterprise_server(suid, entity_id, entity_suid, name, ip, port, username, passwd) "
                    "values(:suid, :entity_id, :entity_suid, :name, :ip, :port, :username, :passwd) "
                ),
                {
                    "suid": shortuuid.ShortUUID().random(10),
                    "entity_id": entity_id,
                    "entity_suid": entity_suid,
                    "name": name,
                    "ip": ip,
                    "port": port,
                    "username": username,
                    "passwd": aes.encrypt(settings.enterprise_aes_key, passwd)
                }
            )
            conn.commit()

        self.finish()


class EditHandler(APIHandler):
    @authenticated
    @operation_log("企业项目", "服务器管理", "编辑", "编辑服务器", "")
    def post(self):
        server_id = self.get_int_argument("id")
        name = self.get_escaped_argument('name', '')
        ip = self.get_escaped_argument('ip', '')
        port = self.get_int_argument("port", 22)
        username = self.get_escaped_argument('username', '')
        passwd = self.get_escaped_argument('passwd', '')
        with self.app_mysql.connect() as conn:
            conn.execute(
                text(
                    "update enterprise_server "
                    "set name=:name, ip=:ip, port=:port, username=:username, passwd=:passwd where id=:id"
                ), {
                    "id": server_id,
                    "name": name,
                    "ip": ip,
                    "port": port,
                    "username": username,
                    "passwd": aes.encrypt(settings.enterprise_aes_key, passwd)
                })
            conn.commit()

        self.finish()


class ListHandler(APIHandler):
    """
    - 描述:服务器列表
    - 请求方式:post
    - 请求参数:
    > - entity_id, int, 企业id
    > - status, int, 1000/all/默认, 1001/在线,1002/离线
    > - pageNo, int,
    > - pageSize, int
    - 返回值:
    ```
    {
        "count": 123,
        "data": [
            {
                "id": 123,
                "name": "xx",
                "status": 1001, # 状态, 1001/在线,1002/离线
                "cpu": 123,
                "mem": 123,
                "storage": 213,
                "gpu": 123,
            },
            ...
        ]
    }
```
    """

    @authenticated
    @operation_log("企业项目", "服务器管理", "查询", "查询服务器列表", "")
    def post(self):
        entity_id = self.get_int_argument('entity_id')
        status = self.get_int_argument("status")
        pageNo = self.get_int_argument("pageNo", 1)
        pageSize = self.get_int_argument("pageSize", 10)
        if not entity_id:
            raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "entity_id is required")
        if status and status not in (1001, 1002):
            raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "status is invalid")

        with self.app_mysql.connect() as conn:
            p = {}
            sql_count = "select count(1) from enterprise_server where entity_id=:entity_id"
            sql_data = "select id, name, status from enterprise_server where entity_id=:entity_id"
            p.update({"entity_id": entity_id})

            if status:
                sql_count += " and status=:status"
                sql_data += " and status=:status"
                p.update({"status": status})

            count = conn.scalar(text(sql_count), p)

            sql_data += " order by id desc limit :pageSize offset :offset"
            p.update({"offset": (pageNo - 1) * pageSize, "pageSize": pageSize})

            data = conn.execute(text(sql_data), p)
            data = to_json_list(data)

            status_dic = {1001: 0, 1002: 0}
            sql_status = "select status, count(id) c from enterprise_server where entity_id=:entity_id group by status"
            status_cur = conn.execute(text(sql_status), p)
            status_list = to_json_list(status_cur)
            for item in status_list:
                status_dic[item["status"]] = item["c"]
            logging.info("####################### ")
            logging.info(data)
            for item in data:
                item.update(
                    {"cpu": random.randint(20, 30),
                     "mem": random.randint(20, 30),
                     "storage": random.randint(20, 30),
                     "gpu": random.randint(20, 30), })

        self.finish({"count": count, "data": data, "status": status_dic})


class InfoHandler(APIHandler):
    """
    - 描述:服务器信息
    - 请求方式:post
    - 请求参数:
    > - server_id, int, 服务器id
    - 返回值:
    ```
    {
        "name": "xx",
        "ip": "xxx",
        "port": "xxx",
        "username": "xxx",
        "cpu": 123,
        "mem": 123,
        "storage": 213,
        "gpu": 123,
    }
    ```
    """

    @authenticated
    @operation_log("企业项目", "服务器管理", "查询", "查询服务器信息", "")
    def post(self):
        server_id = self.get_int_argument('server_id')
        with self.app_mysql.connect() as conn:
            cur = conn.execute(
                text("select name, ip, port, username from enterprise_server where id=:id"),
                {"id": server_id})
            data = to_json(cur)
            if data:
                data.update(
                    {"cpu": random.randint(20, 30),
                     "mem": random.randint(20, 30),
                     "storage": random.randint(20, 30),
                     "gpu": random.randint(20, 30), })
        self.finish(data)


class DeleteHandler(APIHandler):
    @authenticated
    @operation_log("企业项目", "服务器管理", "删除", "删除服务器", "")
    def post(self):
        server_id = self.get_int_argument('server_id')
        with self.app_mysql.connect() as conn:
            conn.execute(
                text("delete from enterprise_server where id=:id"), {"id": server_id}
            )
            conn.commit()
        self.finish()


class LogHandler(APIHandler):
    """
    - 描述:服务器列表
    - 请求方式:post
    - 请求参数:
    > - server_id, int, 服务器id
    > - pageNo, int
    > - pageSize, int
    - 返回值:
    """

    @authenticated
    def post(self):
        entity_id = self.get_int_argument('entity_id')
        pageNo = self.get_int_argument('pageNo', 1)
        pageSize = self.get_int_argument('pageSize', 10)

        with self.app_mysql.connect() as conn:
            p = {}
            sql_count = "select count(1) from enterprise_server where entity_id=:entity_id"
            sql_data = "select id, name, ip, port from enterprise_server where entity_id=:entity_id"
            p.update({"entity_id": entity_id})

            count = conn.scalar(text(sql_count), p)

            sql_data += " order by id desc limit :pageSize offset :offset"
            p.update({"offset": (pageNo - 1) * pageSize, "pageSize": pageSize})

            data = conn.execute(text(sql_data), p)

            data = to_json_list(data)
        self.finish({"count": count, "data": data})