#! /usr/bin/env python3

import argparse
import os
from typing import *
import requests
import shutil

FERNFLOWER_URL = "https://jitpack.io/com/github/MinecraftForge/FernFlower/master/FernFlower-master.jar"


def generateJarDownloadURL(file_id: int, name: Optional[str] = "unnamed") -> str:
    """Generates the download URL for a specific mod

    Args:
        file_id (int): CurseForge file ID
        name (Optional[str], optional): Mod name. Defaults to "unnamed".

    Returns:
        str: Download URL
    """
    return f"https://www.cursemaven.com/curse/maven/{name}/{file_id}/{name}-{file_id}.jar"


def writeRemoteFileLocally(local_uri: str, url: str):
    os.system(f"wget {url} -O {local_uri}")


def main() -> int:

    # Handle args
    ap = argparse.ArgumentParser(
        prog="cursed", description="A tool to decompile Minecraft mods straight from CurseForge")
    ap.add_argument("name", help="Mod name")
    ap.add_argument("file_id", help="CurseForge file ID", type=int)
    ap.add_argument("-w", "--workspace", help="Path to custom workspace root",
                    default="/tmp/cursedecompiler")
    ap.add_argument("-f", "--fernflower", help="Path to custom FernFlower JAR")
    ap.add_argument("-j", "--java", help="Path to custom Java")
    args = ap.parse_args()

    # Determine Java path
    java_path: str
    if args.java:
        java_path = args.java
    else:
        if os.system("which java"):
            print("Java not in PATH")
            return 1
        else:
            java_path = os.path.expandvars("$JAVA_HOME/bin/java")
    print(f"Using Java: {java_path}")

    # Create the workspace
    if not os.path.exists(f"{args.workspace}/{args.name}"):
        os.makedirs(f"{args.workspace}/{args.name}/source")
        print("Created workspace")

    # Determine the location of the mod file
    download_url = generateJarDownloadURL(args.file_id, args.name)
    print(f"Found JAR at: {download_url}")

    # Download the mod
    print("Downloading mod JAR")
    compiled_jar_path = f"{args.workspace}/{args.name}/{args.name}.jar"
    writeRemoteFileLocally(compiled_jar_path, download_url)

    # Find FernFlower
    fernflower_path: str
    if not args.fernflower:
        fernflower_path = f"{args.workspace}/fernflower.jar"
        if os.path.isfile(fernflower_path):
            print("Found fernflower")
        else:
            print("Downloading FernFlower")
            writeRemoteFileLocally(fernflower_path, FERNFLOWER_URL)
    else:
        print("Using custom fernflower")
        fernflower_path = args.fernflower

    # Decompile
    command = f"{java_path} -jar {fernflower_path} {compiled_jar_path} {args.workspace}/"
    print(f"{command}")
    status = os.system(command)

    # Extract
    os.system(
        f"unzip -d{args.workspace}/{args.name}/source {args.workspace}/{args.name}.jar ")

    # Tell the user where to find their files
    if status == 0:
        print(
            f"Decompiled sources are in: {args.workspace}/{args.name}/source")

    return status


if __name__ == "__main__":
    exit(main())