# -*- coding: utf-8 -*-
# TBlock - An anticapitalist ad-blocker that uses the hosts file
# Copyright (C) 2021 Twann <twann@ctemplar.com>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# Standard libraries
import os.path
import sys

# External libraries
from colorama import Fore, Style

# Local libraries
from .config import Path, Var, PROTECTING_STATUS, Font


def update_hosts(all_rules: dict) -> None:
    """Update the hosts file with a set of rules

    Args:
        all_rules (dict): Dictionary returned by tblock.rules.get_all_rules()
    """
    print(f'{Font.BOLD}==> Updating hosts file{Font.DEFAULT}')
    new_hosts = '\n\n# BEGIN BLOCKING RULES\n'
    all_rules_count = len(all_rules.keys())
    count = 1
    load_character = '|'
    for domain in all_rules:
        if count < len(all_rules):
            print(f' [{Fore.YELLOW}{load_character}{Style.RESET_ALL}] Retrieving rules '
                  f'({count}/{all_rules_count})', end='\r')
            # Show process
            if load_character == '|' and not count % 500:
                load_character = '/'
            elif load_character == '/' and not count % 500:
                load_character = '-'
            elif load_character == '-' and not count % 500:
                load_character = '\\'
            elif load_character == '\\' and not count % 500:
                load_character = '|'
        else:
            print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Retrieving rules ({count}/{all_rules_count})')
        if all_rules[domain]['policy'] == 'block':
            new_hosts += f'{Var.DEFAULT_IP}    {domain}\n'
        elif all_rules[domain]['policy'] == 'redirect':
            new_hosts += f'{all_rules[domain]["ip"]}    {domain}\n'
        count += 1
    if not os.path.isfile(Path.HOSTS_BACKUP):
        print(f' [{Fore.YELLOW}|{Style.RESET_ALL}] Backing up previous hosts file', end='\r')
        with open(Path.HOSTS, 'rt') as h:
            default_hosts_content = h.read()
        with open(Path.HOSTS_BACKUP, 'wt') as h:
            h.write(default_hosts_content)
        print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Backing up previous hosts file')
    else:
        with open(Path.HOSTS_BACKUP, 'rt') as h:
            default_hosts_content = h.read()
    new_hosts = default_hosts_content + new_hosts
    new_hosts = '# This file is automatically generated by TBlock\n' \
                '# To edit it manually, run "tblock -D" first. Otherwise, all your modifications will be ' \
                'overwritten.\n\n' + new_hosts
    with open(Path.HOSTS_VERIFICATION, 'wt') as f:
        f.write(new_hosts)
    with open(Path.HOSTS, 'wt') as f:
        f.write(new_hosts)
    if not PROTECTING_STATUS:
        print(
            f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Protection is now {Fore.GREEN}enabled{Style.RESET_ALL}'
        )
    print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Hosts file successfully updated')


def restore_hosts() -> None:
    print(f'{Font.BOLD}==> Restoring previous hosts file{Font.DEFAULT}')
    print(f' [{Fore.YELLOW}|{Style.RESET_ALL}] Restoring default hosts file', end='\r')
    try:
        with open(Path.HOSTS_BACKUP, 'rt') as f:
            default_hosts_content = f.read()
        with open(Path.HOSTS, 'wt') as f:
            f.write(default_hosts_content)
    except (FileNotFoundError, PermissionError):
        print(f' [{Fore.RED}x{Style.RESET_ALL}] Restoring default hosts file')
        sys.exit(f'{Fore.RED}ERROR: default hosts file already restored{Style.RESET_ALL}')
    else:
        print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Restoring default hosts file')
    print(f' [{Fore.YELLOW}|{Style.RESET_ALL}] Removing previous hosts file backup', end='\r')
    os.remove(Path.HOSTS_BACKUP)
    print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Removing previous hosts file backup')
    print(f' [{Fore.GREEN}{Font.CHECK_MARK}{Style.RESET_ALL}] Protection is now {Fore.RED}disabled{Style.RESET_ALL}')
