import re, os, sys
#sys.path.append(os.path.dirname(os.path.abspath(__file__)))

class minimake:
    def __init__(self):
        # Dictionary to store the target as keys and a tuple of source files and commands as values
        self.targets = {}

    def add_target(self, target_file, source_files, commands):
        """
        Add a target with its dependencies and the commands to build it.

        :param target_file: String, the name of the target file
        :param source_files: List of strings, the source files the target depends on
        :param commands: List of strings, the commands needed to build the target
        """
        if target_file in self.targets:
            raise ValueError(f"Target {target_file} already exists.")
        self.targets[target_file] = (source_files, commands)

    def write_makefile(self, output_filename):
        """
        Writes a Makefile with all added targets.

        :param output_filename: String, the path to the output Makefile
        """
        with open(output_filename, 'w') as file:
            file.write("# Makefile generated by minimake\n\n")
            file.write("all: " + " ".join(self.targets.keys()) + "\n\n")
            for target, (sources, commands) in self.targets.items():
                # Write the target and its dependencies
                file.write(f"{target}: {' '.join(sources)}\n")
                # Write each command prefixed by a tab character
                for command in commands:
                    file.write(f"\t{command}\n")
                file.write("\n")  # add a newline for readability between targets

def create_source_files():
    with open("main.c", "w") as f:
        f.write(
            """#include "utils.h"
int main() {
    return print_hello();
}
"""
        )

    with open("utils.c", "w") as f:
        f.write(
            """#include <stdio.h>
int print_hello() {
    printf("Hello, world!\\n");
    return 0;
}
"""
        )

    with open("utils.h", "w") as f:
        f.write(
            """#ifndef UTILS_H
#define UTILS_H
int print_hello();
#endif
"""
        )

# Example usage
if __name__ == "__main__":
    create_source_files()
    mm = minimake()
    mm.add_target("program.exe", ["main.o", "utils.o"], ["gcc -o program.exe main.o utils.o"])
    mm.add_target("main.o", ["main.c", "utils.h"], ["gcc -c main.c"])
    mm.add_target("utils.o", ["utils.c", "utils.h"], ["gcc -c utils.c"])
    mm.write_makefile("Makefile")