from datetime import datetime
import os
import argparse
from log_parser import LogParser
import json
import re


def find_crash_directories(base_dir="/var/crash"):
    directories = []
    for entry in os.listdir(base_dir):
        if entry == "." or entry == "..":
            continue

        entry_path = os.path.join(base_dir, entry)
        if os.path.isdir(entry_path):
            directories.append(entry_path)
    return directories


def check_for_vmcore_dmesg(directory):
    vmcore_dmesg_path = os.path.join(directory, "vmcore-dmesg.txt")
    if os.path.exists(vmcore_dmesg_path) and os.path.isfile(vmcore_dmesg_path):
        lg = LogParser()
        detail = lg.parse_file(vmcore_dmesg_path)
        return detail.to_dict()
    return None


def get_core_time(fname):
    pat = re.compile(r"(\d+)-(\d+)-(\d+)-(\d+):(\d+):(\d+)")
    m = pat.search(fname)
    return m.group(0) if m else None


def range_check(start, end, core_time):
    core_time = datetime.strptime(core_time, "%Y-%m-%d-%H:%M:%S")
    start_time = datetime.strptime(start, "%Y-%m-%d %H:%M:%S") if start else None
    end_time = datetime.strptime(end, "%Y-%m-%d %H:%M:%S") if end else None
    if start_time and core_time < start_time:
        return False
    if end_time and core_time > end_time:
        return False
    return True


def parse_args():
    parser = argparse.ArgumentParser(description="crash dmesg diagnose tool")
    parser.add_argument(
        "-d",
        "--crashdir",
        type=str,
        required=False,
        default="",
        help="crash directory",
    )
    parser.add_argument(
        "-s",
        "--starttime",
        type=str,
        required=False,
        default="",
        help="start time (format: YYYY-MM-DD HH:MM:SS)",
    )
    parser.add_argument(
        "-e",
        "--endtime",
        type=str,
        required=False,
        default="",
        help="end time (format: YYYY-MM-DD HH:MM:SS)",
    )
    return parser.parse_args()


if __name__ == "__main__":
    args = parse_args()
    crash_list = []
    if args.crashdir:
        check_for_vmcore_dmesg(args.crashdir)
    else:
        dirs = find_crash_directories()
        for coredir in dirs:
            core_time = get_core_time(coredir)
            if not core_time:
                continue
            if range_check(args.starttime, args.endtime, core_time):
                res = check_for_vmcore_dmesg(coredir)
                if res:
                    res["core_time"] = core_time
                    crash_list.append(
                        {
                            "crashdir": coredir,
                            "detail": res,
                        }
                    )
        crash_list.sort(
            key=lambda x: datetime.strptime(
                x["detail"]["core_time"], "%Y-%m-%d-%H:%M:%S"
            ),
            reverse=True,
        )
    print(json.dumps(crash_list, indent=4, ensure_ascii=False))
