# à mettre dans XXX_LATEX/
import os
import re
import shutil


def create_logdvi(isbn, book):
    """
    Create a log file from the DVI file using dvips.
    """
    cmd = f'dvips -o {isbn}_{book}.ps {isbn}_{book}.dvi 2> logdvi.txt'
    os.system(cmd)
    print(f"Created logdvi.txt for {isbn}_{book}.dvi")


def parse_logdvi(log_file):
    """
    Parse the log file to find the pages where each image appears.
    Returns a dictionary with image names as keys and page numbers as values.
    """
    image_pages = {}
    if not os.path.exists(log_file):
        print(f"Error: {log_file} does not exist.")
        return image_pages

    with open(log_file, 'r', encoding='utf-8') as f:
        content = f.read()

    # Regex to find image inclusion commands in the log file
    page_pattern = re.compile(r'\[(\d+)')
    image_pattern = re.compile(r'<.*?/(.*?\.eps)>')

    for page_match in page_pattern.finditer(content):
        page_number = int(page_match.group(1))
        start = page_match.end()
        end = content.find(']', start)
        if end == -1:
            continue
        page_content = content[start:end]
        for image_name in image_pattern.findall(page_content):
            image_name = os.path.basename(image_name)  # Extract only the file name
            if image_name not in image_pages:
                image_pages[image_name] = page_number
                print(f"Found image: {image_name} on page: {page_number}")

    return image_pages


def rename_images(image_pages, images_dir):
    """
    Rename the images in the images directory based on the page numbers.
    Returns a dictionary with old image names as keys and new image names as values.

    Règle :
      - le nom est de la forme "xxx_qqchose.eps" (3 caractères puis underscore) ;
      - si "xxx" désigne déjà la page, on ne fait rien ;
      - sinon, on remplace le préfixe par le numéro de page.
    """
    renamed_images = {}
    for image_name, page_number in image_pages.items():
        if image_name == "ILpubEce.eps" or re.match(r'Picto.*\.eps', image_name):
            print(f"Skipping {image_name} as it is excluded from renaming.")
            continue

        # Sécurité : le nom doit bien commencer par "xxx_"
        if len(image_name) < 4 or image_name[3] != '_':
            print(f"Skipping {image_name}: does not match the 'xxx_' prefix pattern.")
            continue

        old_prefix = image_name[:3]
        new_prefix = f"{page_number:03d}"

        # Cas "Sinon, rien n'est fait" : préfixe déjà correct
        if old_prefix == new_prefix:
            print(f"Skipping {image_name}: prefix '{old_prefix}_' already matches page {page_number}.")
            continue

        tmp_name = image_name[4:]
        new_name = f"{new_prefix}_{tmp_name}"

        old_path = os.path.join(images_dir, image_name)
        new_path = os.path.join(images_dir, new_name)

        if os.path.exists(old_path):
            shutil.move(old_path, new_path)
            print(f"Renamed {old_path} to {new_path}")
            renamed_images[image_name] = new_name
        else:
            print(f"Warning: {old_path} does not exist and was not renamed.")

    return renamed_images


def update_latex_files(renamed_images, src_dir):
    """
    Update the LaTeX source files with the new image names.

    Le remplacement se fait via une expression régulière qui exige que le nom
    soit délimité par des accolades, c'est-à-dire qu'il corresponde exactement
    à l'argument d'un \\includegraphics{...}. On accepte aussi une extension
    .eps explicite à l'intérieur des accolades.

    Cela empêche le bug suivant :
        remplacer "000_nom" -> "147_nom" risquait, avec str.replace, de
        modifier aussi le sous-mot "000_nom" présent dans "000_nomCorr".
    Avec le motif {000_nom} -> {147_nom}, "000_nomCorr" n'est jamais touché
    car après "000_nom" il y a "Corr" et non une accolade fermante.
    """
    # Pré-compilation des motifs (une fois pour toutes les répétitions)
    replacement_specs = []
    for old_name, new_name in renamed_images.items():
        old_base = os.path.splitext(old_name)[0]
        new_base = os.path.splitext(new_name)[0]
        if old_base == new_base:
            continue
        # ( {  )  old_base  ( .eps?  } )
        pattern = re.compile(
            r'(\{)' + re.escape(old_base) + r'((?:\.eps)?\})'
        )
        replacement_specs.append((pattern, new_base))

    if not replacement_specs:
        print("No replacement to apply in LaTeX files.")
        return

    for root, _, files in os.walk(src_dir):
        for file in files:
            if not file.endswith('.tex'):
                continue
            file_path = os.path.join(root, file)
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()

            original_content = content
            for pattern, new_base in replacement_specs:
                # Le lambda capte new_base par défaut pour éviter le piège de
                # capture tardive sur la variable de boucle.
                content = pattern.sub(
                    lambda m, nb=new_base: m.group(1) + nb + m.group(2),
                    content,
                )

            if content != original_content:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(content)
                print(f"Updated {file_path}")


def main():
    # Directories
    current_dir = os.path.dirname(os.path.abspath(__file__))
    isbn = os.path.basename(current_dir).split('_')[0]
    book = next(
        f.split('_', 1)[1].rsplit('.', 1)[0]
        for f in os.listdir(current_dir)
        if f.startswith(isbn + '_') and f.endswith('.tex')
    )
    images_dir = os.path.join(os.path.dirname(current_dir), f"{isbn}_IMAGES")
    src_dir = os.path.join(current_dir, 'src')
    log_file = os.path.join(current_dir, 'logdvi.txt')

    # Create log file from DVI
    create_logdvi(isbn, book)

    # Parse log file to find image pages
    image_pages = parse_logdvi(log_file)
    if not image_pages:
        print("No images found in the log file.")
        return

    # Rename images
    renamed_images = rename_images(image_pages, images_dir)
    if not renamed_images:
        print("No images were renamed.")
        return

    # Update LaTeX source files
    update_latex_files(renamed_images, src_dir)

if __name__ == "__main__":
    main()
