#include "../includes/woody.h"

int elf_magic_numbers(char *str)
{
	return (!ft_strncmp(str, ELFMAG, SELFMAG));
}

void	encrypt_zone(char *file, unsigned long int offset, unsigned long int size)
{
	size_t i = 0;
	while (i < size)
	{
		file[offset + i] = 0;
		++i;
	}
}

int		save_elf(char *path, char *file, unsigned long int size)
{
	int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0755);
    if (fd == -1) {
		ft_printf("Error: Failed to create new file \'%s\'\n", path);
		return EXIT_FAILURE;
    }

    if (write(fd, file, size) == -1) {
        close(fd);
        ft_printf("Error: Failed to write new file \'%s\'\n", path);
        return EXIT_FAILURE;
    }

    if (close(fd) == -1) {
		ft_printf("Error: Failed to close new file \'%s\'\n", path);
        return EXIT_FAILURE;
    }
	return EXIT_SUCCESS;
}

int woody(t_efl_content *file_content)
{
	Elf64_Ehdr *Ehdr = (Elf64_Ehdr *)secure_access(file_content->file, file_content->file_size, 0, sizeof(Elf64_Ehdr));

	if (!Ehdr || !elf_magic_numbers(file_content->file) || Ehdr->e_ident[EI_CLASS] != 2)
	{
		ft_printf("Error: \'%s\' is not a valid 64-bit ELF file\n", file_content->file_path);
		return EXIT_FAILURE;
	}

	Elf64_Shdr *Shdr = (Elf64_Shdr *)secure_access(file_content->file, file_content->file_size, Ehdr->e_shoff, sizeof(Elf64_Shdr));
	if (Shdr == NULL || !secure_access(file_content->file, file_content->file_size, Ehdr->e_shoff, Ehdr->e_shnum * sizeof(Elf64_Shdr)))
	{
		return ft_put_error("Corrupted file");
	}
	if (file_content->file_size > Ehdr->e_shoff + Ehdr->e_shnum * sizeof(Elf64_Shdr))
	{
		printf("extra_data !\n"); // save it in file_content->extra_data and append it to the end of the woody file ? Could be dangerous
	}

	Elf64_Shdr *symbols_table = NULL;
    for (int i = 0; i < Ehdr->e_shnum; i++) {
		if (Shdr[i].sh_type == SHT_SYMTAB) {
            symbols_table = secure_access(file_content->file, file_content->file_size, Ehdr->e_shoff + (i * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr));
        }
    }
	if (symbols_table == NULL)
		return ft_put_error("Corrupted file");

    Elf64_Shdr *strtab_header = (Elf64_Shdr *)secure_access(file_content->file, file_content->file_size, Ehdr->e_shoff + (symbols_table->sh_link * Ehdr->e_shentsize), sizeof(Elf64_Shdr)); 
	if (!strtab_header)
		return ft_put_error("Corrupted file");


	if (strtab_header->sh_offset + strtab_header->sh_size > file_content->file_size)
	{
		return ft_put_error("Encrypt after the end of the file");
	}

	char *woody = malloc(file_content->file_size);
	ft_memcpy(woody, file_content->file, file_content->file_size);

	encrypt_zone(woody, strtab_header->sh_offset , strtab_header->sh_size);
	
	return save_elf("woody", woody, file_content->file_size);
}