import requests
from zipfile import ZipFile 
import io, os
import argparse
from generate_nexus_upload_path import split_version 
from build_go_modules import zip_files, generate_checksum_file
from actions_logging.app_logging import logger
from github.env import exit_on_error_and_write_summary
import subprocess


def run_lipo(path_x86, path_arm, output_path):
    try:       
        path_to_create = output_path.split('firefly.dylib')[0]
        os.makedirs(f"{os.getcwd()}/{path_to_create}")    
        commands = ["lipo", f"{path_x86}", f"{path_arm}",  "-output", f"{output_path}", "-create"]
        result = subprocess.run(commands, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        logger.info_green(f"Lipo Output: {result.stdout}")
        logger.warning(f"Lipo Errors: {result.stderr}")
    except subprocess.CalledProcessError as e:
        exit_on_error_and_write_summary(f"An error occurred while unifiying the project: {e.stdout, e.stderr}")
    
def download_file_from_nexus(nexus_url, destination_directory, unzip, username, password ):
    print(f"Downloading file: url:{nexus_url}, destination_directory:{destination_directory}, unzip:{unzip}")
    if not os.path.exists(destination_directory):
        os.makedirs(destination_directory)
        print(f"Directory {destination_directory} created.")

    file_name = os.path.basename(nexus_url)
    destination = os.path.join(destination_directory, file_name)

    response = requests.get(nexus_url, auth=(username, password))
    if response.status_code != 200:
        exit_on_error_and_write_summary(f"Download Failed. Got Sttus code: {response.status_code}")
    print(f"Download status code: {response.status_code}")
    response.raise_for_status()

    print(f'File {file_name} downloaded successfully')

    if unzip:
        with ZipFile(io.BytesIO(response.content)) as z:
            z.extractall(destination_directory)
        print(f'File {file_name} unzipped successfully to {destination_directory}')
    else:
        with open(f'{destination}', 'wb') as f:
            f.write(response.content)

def generate_download_urls(nexus_url, repo, version, branch, gha_trigger, gha_run_number, av, arch):
    major, minor, patch, build = split_version(version)
    if gha_trigger == "release":
        return f"https://{nexus_url}/repository/{repo}/firefly/v{major}.{minor}/stable/{patch}/{build}/{'AV' if av else 'NO_AV'}/macOS/{arch}/macOS_{arch}.zip"
    else:
        return f"https://{nexus_url}/repository/{repo}/firefly/{branch if branch == 'refs/heads/main' else 'v' + major+ '.'+ minor}/nightly/130{gha_run_number}/{'AV' if av else 'NO_AV'}/macOS/{arch}/macOS_{arch}.zip"

if __name__ == "__main__":
    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="Get input parameters")
    parser.add_argument('--nexus_url', type=str, nargs='?', help='Nexus repository URL')
    parser.add_argument('--repository', type=str, nargs='?', help='Nexus repository name')
    parser.add_argument('--nexus_user', type=str, nargs='?', help='Nexus username')
    parser.add_argument('--nexus_password', type=str, nargs='?', help='Nexus password')
    parser.add_argument('--version', type=str, nargs='?', help='Latest version of stable build')
    parser.add_argument('--branch', type=str, nargs='?', help='Branch name')
    parser.add_argument('--gha_trigger', type=str, nargs='?', help='Trigger for GH action')
    parser.add_argument('--gha_run_number', type=str, nargs='?', help='Run number for GH action')
    parser.add_argument('--add_av', type=str, nargs='?', help='AV flag')

    args = parser.parse_args()
    if args.add_av == "True" or args.add_av == "true":
        add_av = True
    else:
        add_av = False
    run_list = [True, False] if add_av else [True]
    for av in run_list:
        for arch in ["ARM64", "X64"]:
            url = generate_download_urls(args.nexus_url, args.repository,  args.version, args.branch, args.gha_trigger, args.gha_run_number, av, arch)
            download_file_from_nexus(url, f"build/{'av' if av else 'no_av'}/{arch}", True, args.nexus_user, args.nexus_password)
    run_lipo(f"build/av/ARM64/firefly.dylib", f"build/av/X64/firefly.dylib", f"build/unified/av/firefly.dylib")
    generate_checksum_file("build/unified/av/firefly.dylib")
    zip_files("firefly.zip", "build/unified/av/", "firefly.dylib", "checksum_SHA256.txt")
    if  add_av:
        run_lipo(f"build/no_av/ARM64/firefly.dylib", f"build/no_av/X64/firefly.dylib", f"build/unified/no_av/firefly.dylib")
        generate_checksum_file("build/unified/no_av/firefly.dylib")
        zip_files("firefly.zip", "build/unified/no_av/", "firefly.dylib", "checksum_SHA256.txt")
