import json
import os
import pathlib
import string
import threading
import ctypes
import time
from time import sleep
from collections import deque
from zipfile import ZipFile

def is_fixed_drive(drive_path):
    """Проверяет, является ли диск фиксированным (локальным)"""
    try:
        drive_type = ctypes.windll.kernel32.GetDriveTypeW(drive_path)
        # 3 = DRIVE_FIXED (локальный диск)
        # 6 = DRIVE_RAMDISK (RAM-диск)
        return drive_type in (3, 6)
    except:
        return False

def find_all_files(target_file, exclude_dirs=None):
    if exclude_dirs is None:
        exclude_dirs = {'Windows', 'Program Files', 'Program Files (x86)',
                        'ProgramData', 'AppData', 'System Volume Information',
                        '$Recycle.Bin', 'Recycler', 'Recovery'}
    found_files = []
    lock = threading.Lock()

    # Получаем список дисков и фильтруем только фиксированные
    drives = [f"{d}:\\" for d in string.ascii_uppercase
              if os.path.exists(f"{d}:\\") and is_fixed_drive(f"{d}:\\")]

    print(f"Обнаружены локальные диски: {drives}")

    def search_in_drive(drive):
        try:
            queue = deque([drive])
            while queue:
                current_dir = queue.popleft()
                try:
                    with os.scandir(current_dir) as entries:
                        for entry in entries:
                            if entry.name in exclude_dirs:
                                continue

                            if entry.is_file() and entry.name == target_file:
                                with lock:
                                    found_files.append(entry.path)
                                    print(f"Найден файл: {entry.path}")
                            elif entry.is_dir():
                                queue.append(entry.path)
                except (PermissionError, OSError):
                    continue
        except Exception as e:
            print(f"Ошибка при поиске на диске {drive}: {e}")

    threads = []
    for drive in drives:
        thread = threading.Thread(target=search_in_drive, args=(drive,))
        thread.daemon = True
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()
    return found_files



def unzip_file(zip_filepath, extract_to_dir=None, password=None):
    """
    Unzips a specified ZIP file to a target directory.

    Args:
        zip_filepath (str): The path to the ZIP file to be unzipped.
        extract_to_dir (str, optional): The directory where the contents
                                        should be extracted. If None,
                                        contents are extracted to the
                                        current working directory.
        password (bytes, optional): The password for encrypted ZIP files.
                                    Must be provided as bytes (e.g., b'mysecret').
    """
    if not os.path.exists(zip_filepath):
        print(f"Error: ZIP file not found at '{zip_filepath}'")
        return

    if extract_to_dir and not os.path.exists(extract_to_dir):
        os.makedirs(extract_to_dir) # Create the directory if it doesn't exist

    try:
        with ZipFile(zip_filepath, 'r') as zip_ref:
            if password:
                zip_ref.extractall(path=extract_to_dir, pwd=password)
            else:
                zip_ref.extractall(path=extract_to_dir)
        print(f"Successfully unzipped '{zip_filepath}' to '{extract_to_dir or os.getcwd()}'")
    except Exception as e:
        print(f"Error unzipping '{zip_filepath}': {e}")


from urllib.parse import urlparse

def is_valid_url_format(url_string):
    try:
        result = urlparse(url_string)
        return all([result.scheme, result.netloc])
    except ValueError:
        return False

import requests

def is_url_accessible(url,  timeout=5):
    try:
        response = requests.head(url, timeout=5)  # Use HEAD request for efficiency
        return response.status_code == 200  # Check for a successful status code (200 OK)
    except requests.exceptions.RequestException:
        return False

import os

from libs.spider_logger import logger
from libs.pyconf import pyconf


class Env:
    def __init__(self):
        self.app_dir = os.path.abspath(os.curdir) + "/"
        self.etc = self.app_dir + "etc/"
        self.var = self.app_dir + "var/"
        self.game_dir = None
        self.debug = False

import hashlib

def calculate_sha256(file_path, chunk_size=65536):
    sha256_hash = hashlib.sha256()
    try:
        with open(file_path, "rb") as f:
            while True:
                data = f.read(chunk_size)
                if not data:
                    break
                sha256_hash.update(data)
        return sha256_hash.hexdigest()
    except FileNotFoundError:
        print(f"Error: File not found at '{file_path}'")
        return None
    except Exception as e:
        print(f"An error occurred: {e}")
        return None


def get_text_file_content_from_http(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # Raise an exception for bad status codes (4xx or 5xx)
        return response.text
    except requests.exceptions.RequestException as e:
        print(f"Error retrieving content from {url}: {e}")
        return None
