Draft

import os

def encode_message_to_coords(message: str) -> list[tuple[int, int, str]]:
    """
    Encodes a string message into a list of (x, y, character) coordinates.
    The message is encoded sequentially, filling a conceptual grid row by row.
    """
    coordinates = []
    x, y = 0, 0
    max_x_per_row = 50 # Arbitrary max width for visual clarity in a text file

    for char in message:
        coordinates.append((x, y, char))
        x += 1
        if x >= max_x_per_row:
            x = 0
            y += 1
    return coordinates

def save_coords_to_file(coordinates: list[tuple[int, int, str]], filename: str):
    """
    Saves the list of coordinates to a text file, one coordinate per line.
    """
    try:
        with open(filename, 'w') as f:
            for x, y, char in coordinates:
                f.write(f"{x} {y} {char}\n")
        print(f"Coordinates saved to {filename}")
    except IOError as e:
        print(f"Error saving coordinates to file: {e}")
        raise

def load_coords_from_file(filename: str) -> list[tuple[int, int, str]]:
    """
    Loads coordinates from a text file. Each line should be in the format 'x y char'.
    """
    coordinates = []
    try:
        with open(filename, 'r') as f:
            for line in f:
                parts = line.strip().split(maxsplit=2) # maxsplit=2 to handle multi-word chars if needed, though here it's single char
                if len(parts) == 3:
                    try:
                        x = int(parts[0])
                        y = int(parts[1])
                        char = parts[2]
                        coordinates.append((x, y, char))
                    except ValueError:
                        print(f"Skipping malformed line (non-integer coordinates): {line.strip()}")
                else:
                    print(f"Skipping malformed line (incorrect parts count): {line.strip()}")
    except FileNotFoundError:
        print(f"Error: File '{filename}' not found.")
        raise
    except IOError as e:
        print(f"Error reading file '{filename}': {e}")
        raise
    return coordinates

def build_grid(coordinates: list[tuple[int, int, str]]) -> list[list[str]]:
    """
    Reconstructs a 2D grid from a list of (x, y, character) coordinates.
    The grid will be sized to fit all characters.
    """
    if not coordinates:
        return []

    max_x = 0
    max_y = 0
    for x, y, _ in coordinates:
        if x > max_x:
            max_x = x
        if y > max_y:
            max_y = y

    # Initialize grid with spaces
    grid = [[' ' for _ in range(max_x + 1)] for _ in range(max_y + 1)]

    # Place characters on the grid
    for x, y, char in coordinates:
        if 0 <= y <= max_y and 0 <= x <= max_x: # Ensure coordinates are within bounds
            grid[y][x] = char
        else:
            print(f"Warning: Coordinate ({x},{y}) out of calculated grid bounds. Skipping character '{char}'.")
    return grid

def decode_grid_to_message(grid: list[list[str]]) -> str:
    """
    Decodes the characters from the grid back into a sequential message.
    It reads row by row, then column by column, collecting non-space characters.
    """
    if not grid:
        return ""

    message_chars = []
    # Assuming the message was encoded sequentially, reading row by row, column by column
    # will reconstruct it in order.
    for row in grid:
        for char in row:
            if char != ' ': # Only collect actual characters, ignore padding spaces
                message_chars.append(char)
    return "".join(message_chars)

def print_grid_to_console(grid: list[list[str]]):
    """
    Prints the grid to the console.
    """
    if not grid:
        print("Empty grid.")
        return
    for row in grid:
        print(''.join(row))

# Example Usage (for testing the script directly)
if __name__ == "__main__":
    # --- Encoding Example ---
    secret_policy_message = "This is a highly confidential corporate policy directive. Unauthorized disclosure is strictly prohibited. All personnel must adhere to these guidelines by 2025-08-01."
    print("--- Encoding Message ---")
    print(f"Original Message:\n{secret_policy_message}\n")
    encoded_coords = encode_message_to_coords(secret_policy_message)
    print(f"Encoded Coordinates (first 5):\n{encoded_coords[:5]}...\n")

    # Save to a temporary file
    temp_encoded_filename = "encoded_policy_document.txt"
    try:
        save_coords_to_file(encoded_coords, temp_encoded_filename)
    except Exception as e:
        print(f"Failed to save encoded file: {e}")
        exit()

    # --- Decoding Example ---
    print("\n--- Decoding Message from File ---")
    try:
        loaded_coords = load_coords_from_file(temp_encoded_filename)
        reconstructed_grid = build_grid(loaded_coords)
        print("\nReconstructed Grid (visual):")
        print_grid_to_console(reconstructed_grid)

        decoded_message = decode_grid_to_message(reconstructed_grid)
        print(f"\nDecoded Message:\n{decoded_message}")

        # Verification
        if decoded_message == secret_policy_message:
            print("\nDecoding successful: Original message matches decoded message!")
        else:
            print("\nDecoding failed: Messages do NOT match.")

    except Exception as e:
        print(f"Failed to decode file: {e}")

    finally:
        # Clean up temporary file
        if os.path.exists(temp_encoded_filename):
            os.remove(temp_encoded_filename)
            print(f"\nCleaned up temporary file: {temp_encoded_filename}")

en_USEnglish