# retoor <retoor@molodetz.nl>

from __future__ import annotations

from ..spec import Action
from ._shared import body, confirm, path, query, upload


PROJECT_FILE_ACTIONS: tuple[Action, ...] = (
    Action(
        name="project_list_files",
        method="GET",
        path="/projects/{project_slug}/files",
        summary="List every file and directory in a project filesystem",
        description="Returns the flat list of nodes (path, type, size, mime). Use it to inspect the project tree before reading or writing files.",
        params=(path("project_slug", "Project slug or uid."),),
        requires_auth=False,
    ),
    Action(
        name="project_read_file",
        method="GET",
        path="/projects/{project_slug}/files/raw",
        summary="Read one file from a project filesystem",
        description="Returns the file metadata plus the text content. Binary files return a url instead of content.",
        params=(
            path("project_slug", "Project slug or uid."),
            query(
                "path",
                "Relative file path inside the project, e.g. src/main.py.",
                required=True,
            ),
        ),
        requires_auth=False,
    ),
    Action(
        name="project_write_file",
        method="POST",
        path="/projects/{project_slug}/files/write",
        summary="Create or overwrite a whole text file in a project (parent directories are created automatically)",
        description=(
            "Replaces the ENTIRE file with the content you send. Creating a new file needs no prior "
            "read, but overwriting an existing one requires reading it first (project_read_file). "
            "For an existing file prefer the surgical line tools (project_replace_lines, "
            "project_insert_lines, project_delete_lines, project_append_file) instead of rewriting it, "
            "and never batch several writes in one turn. Use this only to create a new file or fully "
            "rewrite a small one. Missing parent directories are created recursively."
        ),
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative file path, e.g. src/app/main.py.", required=True),
            body("content", "Full file content.", required=True),
        ),
    ),
    Action(
        name="project_read_lines",
        method="GET",
        path="/projects/{project_slug}/files/lines",
        summary="Read a 1-indexed line range of a text file in a project",
        description=(
            "Returns {path, start, end, total_lines, lines, content} for the requested range. Use it "
            "to inspect part of a large file before editing, and to learn total_lines so you can target "
            "the right range with the line-edit tools."
        ),
        params=(
            path("project_slug", "Project slug or uid."),
            query("path", "Relative file path inside the project.", required=True),
            query("start", "First line to read (1-indexed, default 1)."),
            query("end", "Last line to read (inclusive); omit for end of file."),
        ),
        requires_auth=False,
    ),
    Action(
        name="project_replace_lines",
        method="POST",
        path="/projects/{project_slug}/files/replace-lines",
        summary="Replace an inclusive 1-indexed line range of a text file with new content",
        description=(
            "Surgically rewrites lines start..end (inclusive) with content (which may be any number of "
            "lines, or empty to delete the range). The preferred way to edit an existing file: it leaves "
            "the rest of the file untouched and never overflows the model output limit."
        ),
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative file path.", required=True),
            body("start", "First line to replace (1-indexed).", required=True),
            body("end", "Last line to replace (inclusive).", required=True),
            body("content", "Replacement text for those lines (empty deletes them)."),
        ),
    ),
    Action(
        name="project_insert_lines",
        method="POST",
        path="/projects/{project_slug}/files/insert-lines",
        summary="Insert content before a 1-indexed line of a text file",
        description=(
            "Inserts content before line 'at' without touching existing lines. Use at=1 to prepend and "
            "at=total_lines+1 to insert at the end."
        ),
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative file path.", required=True),
            body(
                "at",
                "Insert before this 1-indexed line (1 prepends, total+1 appends).",
                required=True,
            ),
            body("content", "Text to insert.", required=True),
        ),
    ),
    Action(
        name="project_delete_lines",
        method="POST",
        path="/projects/{project_slug}/files/delete-lines",
        summary="Delete an inclusive 1-indexed line range from a text file",
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative file path.", required=True),
            body("start", "First line to delete (1-indexed).", required=True),
            body("end", "Last line to delete (inclusive).", required=True),
        ),
    ),
    Action(
        name="project_append_file",
        method="POST",
        path="/projects/{project_slug}/files/append",
        summary="Append content to the end of a text file in a project",
        description="Adds content as new lines at the end of the file. Use it to grow a large file across turns without resending the whole thing.",
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative file path.", required=True),
            body("content", "Text to append.", required=True),
        ),
    ),
    Action(
        name="project_upload_file",
        method="POST",
        path="/projects/{project_slug}/files/upload",
        summary="Upload a local file into a project directory (parents created automatically)",
        params=(
            path("project_slug", "Project slug or uid."),
            upload("file", "Local filesystem path of the file to upload."),
            body("path", "Target directory inside the project, empty for the root."),
        ),
    ),
    Action(
        name="project_make_dir",
        method="POST",
        path="/projects/{project_slug}/files/mkdir",
        summary="Create a directory (and parents) in a project filesystem",
        params=(
            path("project_slug", "Project slug or uid."),
            body(
                "path", "Relative directory path, e.g. src/components.", required=True
            ),
        ),
    ),
    Action(
        name="project_move_file",
        method="POST",
        path="/projects/{project_slug}/files/move",
        summary="Move or rename a file or directory within a project",
        params=(
            path("project_slug", "Project slug or uid."),
            body("from_path", "Existing path.", required=True),
            body("to_path", "New path.", required=True),
        ),
    ),
    Action(
        name="project_delete_file",
        method="POST",
        path="/projects/{project_slug}/files/delete",
        summary="Delete a file or directory (recursive) from a project filesystem (project owner, or any project when you are an administrator). Soft delete, confirmation required",
        params=(
            path("project_slug", "Project slug or uid."),
            body("path", "Relative path to delete.", required=True),
            confirm(),
        ),
    ),
)
