import os


from .consts import (
    FILE_USERS,
    FILE_PASSWORDS,
    FILE_WORDLIST,
    FILE_USERPASS,
    FILE_NTLM_HASHES,
    FOLDER_HOSTS,
    FILE_IP_ALL,
    FOLDER_NMAP,
    FILE_CUSTOM_ROCKYOU,
    PATH_ROCKYOU,
)
from .utils import read_file_as_list, logger, write_file_from_list
from .nmap_functions import ip_from_gnmap


def consolidate_all(mission_path, *, fast: bool = None):
    """Main function to call all consolidations functions"""
    if fast is None:
        fast = False

    consolidate_user_pass_text_files(mission_path)
    # FIXME: fix consolidate_ip_and_ports
    # consolidate_ip_and_ports(mission_path)
    if not fast:
        consolidate_custom_rockyou(mission_path)


def consolidate_user_pass_text_files(mission_path):
    """Consolidate credentials files
    - add users.txt and passwords.txt on wordlist.txt
    - create custom_rockyou.txt that is a merge of rockyou and wordlist.txt"""
    files = {
        FILE_USERS: {},
        FILE_PASSWORDS: {},
        FILE_WORDLIST: {},
        FILE_USERPASS: {},
        FILE_NTLM_HASHES: {},
    }

    for file_name, file_value in files.items():
        path_file = os.path.join(mission_path, file_name)
        data = read_file_as_list(path_file)
        # TODO: add logger.info to check if we removed
        data = sorted(set(data))
        old_len_data = len(data)

        # TODO: for each host consolidate also their things
        # Merge data of each host into data of mission (passwords, users, ...)
        for host in os.listdir(os.path.join(mission_path, FOLDER_HOSTS)):
            path_host_file = os.path.join(mission_path, FOLDER_HOSTS, host, file_name)
            data.extend(read_file_as_list(path_host_file))

        file_value["data"] = data
        file_value["old_len_data"] = old_len_data
        file_value["path"] = path_file

    files[FILE_USERPASS]["data"] = [
        e.split(":", maxsplit=1) for e in files[FILE_USERPASS]["data"]
    ]

    for user, password in files[FILE_USERPASS]["data"]:
        files[FILE_USERS]["data"].append(user)
        files[FILE_PASSWORDS]["data"].append(password)

    for password in files[FILE_PASSWORDS]["data"]:
        files[FILE_WORDLIST]["data"].append(password)

    for user in files[FILE_USERS]["data"]:
        files[FILE_WORDLIST]["data"].append(user)

    files[FILE_USERPASS]["data"] = [f"{e}:{p}" for e, p in files[FILE_USERPASS]["data"]]

    for file_name, file_value in files.items():
        # Remove duplicates and sort data
        file_value["data"] = sorted(set(file_value["data"]))

        # Log number of new entries
        diff_len_data = len(file_value["data"]) - file_value["old_len_data"]
        if diff_len_data:
            logger.info(f"Added {diff_len_data} entry to {file_name}")

        # Write new data
        write_file_from_list(file_value["path"], file_value["data"])


def consolidate_ip_and_ports():
    # FIXME: not working
    ip_addresses = read_file_as_list(FILE_IP_ALL)
    path_nmap_pingsweep = os.path.join(FOLDER_NMAP, "ping_sweep.gnmap")
    if os.path.exists(path_nmap_pingsweep):
        ip_addresses.extend(ip_from_gnmap(path_nmap_pingsweep))

    # Save things
    ip_addresses = sorted(set(ip_addresses))
    write_file_from_list(FILE_IP_ALL, ip_addresses)


def consolidate_custom_rockyou(root_path: str):
    """Create wordlist that is a merge of rockyou and current wordlist"""

    logger.info(f"Writing wordlist.txt and rockyou.txt to {FILE_CUSTOM_ROCKYOU}")
    path_custom_rockyou = os.path.join(root_path, FILE_CUSTOM_ROCKYOU)
    with open(path_custom_rockyou, "wb") as custom_rockyou_file:
        for path in [os.path.join(root_path, FILE_WORDLIST), PATH_ROCKYOU]:
            with open(path, "rb") as f:
                for line in f:
                    custom_rockyou_file.write(line)
