from actions_logging.app_logging import logger
import argparse
from github.env import exit_on_error_and_write_summary
import subprocess
import hashlib
import zipfile
import os

def generate_build_command(build_os, av, build_tags):
    # Generate the build command based on the OS
    basic_build_commands = ["go", "build", "-v", "-x", "-ldflags=-s -w", f"-tags={build_tags}"]
    build_flags_and_directory = ["-buildmode=c-shared", "./attachment-agent/"]
    build_os = build_os.lower()
    no_av = ("\\no_av" if build_os == "windows" else "/no_av") if not av else ""
    if build_os == "windows":
        return basic_build_commands + ["-o", f"attachment-agent\\build{no_av}\\firefly.dll" ] + build_flags_and_directory
    elif build_os == "linux":
        return basic_build_commands + ["-o", f"attachment-agent/build{no_av}/firefly.so", "-buildvcs=false"] + build_flags_and_directory
    elif build_os == "macos":
        return basic_build_commands + ["-o", f"attachment-agent/build{no_av}/firefly.dylib"] + build_flags_and_directory
    else:
        logger.error(f"Invalid OS specified: {build_os}")
        exit_on_error_and_write_summary(f"Invalid OS specified: {build_os}")

def build_go_project(build_os, av, build_tags=False):
    try:
        command = generate_build_command(build_os, av, build_tags=build_tags)
        logger.info(f"Build command: {command}")
        result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        logger.info_green(f"Build Output: {result.stdout}")
        logger.warning(f"Build Errors: {result.stderr}")
    except subprocess.CalledProcessError as e:
        exit_on_error_and_write_summary(f"An error occurred while building the Go project: {e.stdout, e.stderr}")

def generate_file_path(build_os, av):
    build_os = build_os.lower()
    no_av = ("\\no_av" if build_os == "windows" else "/no_av") if not av else ""
    if build_os == "windows":
        return f"attachment-agent\\build{no_av}\\firefly.dll"
    elif build_os == "linux":
        return f"attachment-agent/build{no_av}/firefly.so"
    elif build_os == "macos":
        return f"attachment-agent/build{no_av}/firefly.dylib"
    else:
        logger.error(f"Invalid OS specified: {build_os}")
        exit_on_error_and_write_summary(f"Invalid OS specified: {build_os}")

def generate_checksum_file(filepath):
    # Generate the checksum file based on the OS
    with open(filepath, "rb") as f:
        bytes = f.read()
        checksum = hashlib.sha256(bytes).hexdigest()
    checksum_file = f"{filepath.split('firefly')[0]}checksum_SHA256.txt"
    with open(checksum_file, "w") as f:
        f.write(checksum)

def zip_files(zip_file_name, directory, *files_to_zip):
    with zipfile.ZipFile(f"{directory}{zip_file_name}", 'w') as zipf:
        for file in files_to_zip:
            logger.info(f"Zipping file: {file}")
            zipf.write(f"{directory}{file}", os.path.basename(file))

if __name__ == "__main__":
    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="Get input parameters")
    parser.add_argument('--build_os', type=str, nargs='?', help='For which OS to create build for')
    parser.add_argument('--av', type=str, nargs='?', help='If to use alternate command during build')
    parser.add_argument('--build_tags', type=str, nargs='?', help='Build tags to use during build') 
    args = parser.parse_args()
    if args.av == "true" or args.av == "True":
        av = True
    else:
        av = False
    file_path = generate_file_path(args.build_os, av)
    build_go_project(args.build_os, av, args.build_tags)
    generate_checksum_file(file_path)
    directory = file_path.split("firefly")[0]
    zip_files("firefly.zip",directory, *[f for f in os.listdir(directory) if f != "firefly.h"])