import requests
from packaging.version import Version
import logging
import os
from typing import List, Tuple, Dict

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def check_dependencies(dependencies: List[Tuple[str, str]]) -> None:
    """
    Checks for outdated dependencies against PyPI.

    Args:
        dependencies: A list of tuples, where each tuple contains the package name and its current version.
    """
    for package_name, current_version in dependencies:
        try:
            response = requests.get(f"https://pypi.org/pypi/{package_name}/json")
            response.raise_for_status()  # Raise HTTPError for bad responses (4xx or 5xx)
            latest_version = Version(response.json()["info"]["version"])
            current_version_parsed = Version(current_version)

            if latest_version > current_version_parsed:
                logging.warning(f"Package {package_name} is outdated. Current version: {current_version}, Latest version: {latest_version}")
            else:
                logging.info(f"Package {package_name} is up to date. Current version: {current_version}, Latest version: {latest_version}")

        except requests.exceptions.RequestException as e:
            logging.error(f"Error fetching package information for {package_name}: {e}")
        except KeyError:
            logging.error(f"Could not find version information for {package_name} on PyPI.")
        except Exception as e:
            logging.error(f"An unexpected error occurred while checking {package_name}: {e}")

def parse_requirements_file(file_path: str) -> List[Tuple[str, str]]:
    """
    Parses a requirements file and returns a list of dependencies.

    Args:
        file_path: The path to the requirements file.

    Returns:
        A list of tuples, where each tuple contains the package name and its current version.
    """
    dependencies = []
    try:
        with open(file_path, "r") as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith("#"):
                    parts = line.split("==")
                    if len(parts) == 2:
                        package_name = parts[0].strip()
                        version = parts[1].strip()
                        dependencies.append((package_name, version))
                    else:
                        logging.warning(f"Skipping invalid line in requirements file: {line}")
    except FileNotFoundError:
        logging.error(f"Requirements file not found: {file_path}")
    except Exception as e:
        logging.error(f"Error parsing requirements file: {e}")
    return dependencies

def main() -> None:
    """
    Main function to check for outdated dependencies.
    """
    requirements_file = "requirements.txt"  # Replace with the actual path to your requirements file
    if not os.path.exists(requirements_file):
        logging.error(f"The requirements file {requirements_file} does not exist. Creating a dummy file.")
        with open(requirements_file, "w") as f:
            f.write("requests==2.25.1\n")
            f.write("packaging==20.9\n")


    dependencies = parse_requirements_file(requirements_file)
    if dependencies:
        check_dependencies(dependencies)
    else:
        logging.info("No dependencies found to check.")

if __name__ == "__main__":
    main()