#! /usr/bin/env python
"""
Kubernetes Virtual filesystem for Midnight Commander
* Copyright (c) 2019, Rodrigo Diaz Leven
* Published under 3-clause BSD-style license (see LICENSE file)
"""
from __future__ import print_function
import argparse
from datetime import datetime
import json
import os
import re
import subprocess
import sys
import logging
from pprint import pprint
import subprocess
import json
from dateutil import parser

# set up logging to file - see previous section for more details
logging.basicConfig(
    level=logging.ERROR,
    format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s",
    datefmt="%m-%d %H:%M",
    filename="/tmp/k8sfs.log",
    filemode="a",
)
logging.getLogger("kubernetes.client.rest").setLevel(logging.ERROR)
# define a Handler which writes INFO messages or higher to the sys.stderr

__version__ = 0.11

XDG_CONFIG_HOME = os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))


class K8s:
    helper = None
    arch = None
    full_arch = None

    def __init__(self, arch):
        logging.debug(f"k8fs-context:k8s:init called with {arch}")
        self.full_arch = arch
        self.arch = arch.split("k8s-context")[1]
        self.k8s = K8sHelper(self.arch)

    def list(self):
        logging.debug(f"k8fs-context list called")
        out = subprocess.check_output(
            [
                "kubectl",
                f"--context={self.arch}",
                "get",
                "deploy,pod,rs,svc,ing,sts,job,cm,pdb,secret",
                "--all-namespaces",
                "-o=custom-columns=NAMESPACE:.metadata.namespace,KIND:.kind,NAME:.metadata.name",
                "-o=json",
            ]
        )
        json_out = json.loads(out)
        # pprint(json_out)
        ret = ""
        for item in json_out["items"]:
            m = item["metadata"]
            # pprint(m)
            dt = parser.parse(m["creationTimestamp"])
            # pprint(item)
            if item["kind"] == "Pod":
                # pprint(item)
                m["name"] = self.pod_name(item)

            ret = f"{ret}-rwxr--r-- 1 root root 0 {dt.strftime('%m-%d-%Y %H:%M:%S')} namespaces/{m['namespace']}/{item['kind']}/{m['name']}.yaml\n"
        print(ret.rstrip())
        exit(0)

    def pod_name(self, item):
        m = item["metadata"]
        cont = {"count": 0, "running": 0, "restart": 0}
        for c in item["status"]["containerStatuses"]:
            cont["count"] = cont["count"] + 1
            if "running" in c["state"]:
                cont["running"] = cont["running"] + 1
            cont["restart"] = cont["restart"] + c["restartCount"]

        age = pretty_date(parser.parse(item["status"]["startTime"]))
        return f"{m['name']} {cont['count']}-{cont['running']} {item['status']['phase']} {cont['restart']} {age}"

    def copyin(self, dst, src):
        logging.debug(f"copyin called  {dst} {src}")

    def copyout(self, dst, src):
        logging.debug(f"copyout called  {dst} {src}")
        dst = dst.split("/")
        namespace = dst[1]
        kind = dst[2]
        name = dst[3].split()[0].split(".yaml")[0]
        out = subprocess.check_output(
            [
                "kubectl",
                f"--context={self.arch}",
                f"--namespace={namespace}",
                "get",
                kind,
                name,
                "-o=yaml",
            ]
        )
        with open(src, "wb") as fd:
            fd.write(out)
        exit(0)

    def run(self, dst):
        logging.debug(f"run called  {dst} ")
        dst = dst.split("/")
        namespace = dst[1]
        kind = dst[2]
        name = dst[3].split()[0].split(".yaml")[0]
        out = subprocess.check_output(
            [
                "kubectl",
                f"--context={self.arch}",
                f"--namespace={namespace}",
                "describe",
                kind,
                name,
            ]
        )
        # with open(self.full_arch, "wb") as fd:
        #    fd.write(out)
        print(out.decode("utf-8"))
        out = subprocess.check_output(
            ["kubectl", f"--context={self.arch}", f"--namespace={namespace}", "get", kind, name]
        )
        print(out.decode("utf-8"))


CALL_MAP = {
    "list": lambda a: K8s(a.arch).list(),
    "copyin": lambda a: K8s(a.arch).copyin(a.src, a.dst),
    "copyout": lambda a: K8s(a.arch).copyout(a.src, a.dst),
    "mkdir": lambda a: K8s(a.arch).mkdir(a.dst),
    "rmdir": lambda a: K8s(a.arch).rmdir(a.dst),
    "rm": lambda a: K8s(a.arch).rm(a.dst),
    "run": lambda a: K8s(a.arch).run(a.dst),
}

# """display the file/entire node"""
# template = (
#     "{perms} {links:>4} {uid:<8} {gid:<8} {size:>8} " "{date_time} {fullname}\n"
# )
def test(args):
    h = K8s("...k8s-contextdev-tooling")
    pprint(h.list())


def main2():
    logging.debug("k8sfs-context called main2")
    """parse commandline"""
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(help="supported commands")
    parser_list = subparsers.add_parser("list")
    parser_copyin = subparsers.add_parser("copyin")
    parser_copyout = subparsers.add_parser("copyout")
    parser_rm = subparsers.add_parser("rm")
    parser_mkdir = subparsers.add_parser("mkdir")
    parser_rmdir = subparsers.add_parser("rmdir")
    parser_run = subparsers.add_parser("run")
    parser_test = subparsers.add_parser("test")

    # parser_test.add_argument("arch")
    parser_test.set_defaults(func=test)

    parser_list.add_argument("arch")
    parser_list.set_defaults(func=CALL_MAP["list"])

    parser_copyin.add_argument("arch")
    parser_copyin.add_argument("dst")
    parser_copyin.add_argument("src")
    parser_copyin.set_defaults(func=CALL_MAP["copyin"])

    parser_copyout.add_argument("arch")
    parser_copyout.add_argument("src")
    parser_copyout.add_argument("dst")
    parser_copyout.set_defaults(func=CALL_MAP["copyout"])

    parser_rm.add_argument("arch")
    parser_rm.add_argument("dst")
    parser_rm.set_defaults(func=CALL_MAP["rm"])

    parser_mkdir.add_argument("arch")
    parser_mkdir.add_argument("dst")
    parser_mkdir.set_defaults(func=CALL_MAP["mkdir"])

    parser_rmdir.add_argument("arch")
    parser_rmdir.add_argument("dst")
    parser_rmdir.set_defaults(func=CALL_MAP["rmdir"])

    parser_run.add_argument("arch")
    parser_run.add_argument("dst")
    parser_run.set_defaults(func=CALL_MAP["run"])

    parser.add_argument("--version", action="version", version="%(prog)s " + str(__version__))

    args = parser.parse_args()

    return args.func(args)


def pretty_date(time=False):
    """
    Get a datetime object or a int() Epoch timestamp and return a
    pretty string like 'an hour ago', 'Yesterday', '3 months ago',
    'just now', etc
    """
    from datetime import datetime
    import pytz

    now = datetime.now(pytz.utc)
    if type(time) is int:
        diff = now - datetime.fromtimestamp(time)
    elif isinstance(time, datetime):
        diff = now - time
    elif not time:
        diff = now - now
    second_diff = diff.seconds
    day_diff = diff.days

    if day_diff < 0:
        return ""

    if day_diff == 0:
        if second_diff < 60:
            return str(second_diff) + "s"
        if second_diff < 3600:
            return str(int(second_diff / 60)) + "m"
        if second_diff < 86400:
            return str(int(second_diff / 3600)) + " h"
    if day_diff == 1:
        return "1d"
    if day_diff < 7:
        return str(day_diff) + "d"
    if day_diff < 31:
        return str(int(day_diff / 7)) + "w"
    if day_diff < 365:
        return str(int(day_diff / 30)) + "m"
    return str(int(day_diff / 365)) + "y"


# AAAAAAA NNN OOOOOOOO GGGGGGGG SSSSSSSS DATETIME [PATH/]FILENAME [-> [PATH/]FILENAME[/]]]
class K8sHelper:
    context = None

    def __init__(self, context):
        self.context = context


if __name__ == "__main__":
    sys.exit(main2())

