# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========

import asyncio
import json
import os

from dotenv import load_dotenv

from mirage import MountMode, Workspace
from mirage.resource.trello import TrelloConfig, TrelloResource
from mirage.types import PathSpec

load_dotenv(".env.development")

config = TrelloConfig(
    api_key=os.environ["TRELLO_API_KEY"],
    api_token=os.environ["TRELLO_API_TOKEN"],
)
resource = TrelloResource(config=config)


async def main() -> None:
    ws = Workspace({"/trello": resource}, mode=MountMode.WRITE)

    print("=== not-found errors show the full virtual path ===")
    for cmd in ("cat /trello/__nf_missing__.txt",
                "head /trello/__nf_missing__.txt",
                "stat /trello/__nf_missing__.txt"):
        result = await ws.execute(cmd)
        print(f"$ {cmd}")
        print(f"  exit={result.exit_code}  "
              f"{(await result.stderr_str()).strip()}")

    print("=== ls /trello/workspaces/ ===")
    result = await ws.execute("ls /trello/workspaces/")
    print(await result.stdout_str())

    first_ws = (await result.stdout_str()).strip().splitlines()[0] if (
        await result.stdout_str()).strip() else ""
    if not first_ws:
        print("No workspaces available")
        return

    print(f"=== cat /trello/workspaces/{first_ws}/workspace.json ===")
    result = await ws.execute(
        f"cat /trello/workspaces/{first_ws}/workspace.json")
    print(await result.stdout_str())

    # chmod/chown/touch never hit the Trello API: attrs land in the
    # workspace namespace (durable, snapshot-captured) and merge into
    # dispatch-level stat.
    ws_json = f"/trello/workspaces/{first_ws}/workspace.json"
    print(f"=== metadata overlay on {ws_json} ===")
    meta_res = await ws.execute(f'chmod 640 "{ws_json}"'
                                f' && chown 500:dev "{ws_json}"'
                                f' && touch -t 202601021530 "{ws_json}"')
    print(f"  chmod/chown/touch exit={meta_res.exit_code}")
    meta_st, _ = await ws.dispatch("stat", PathSpec.from_str_path(ws_json))
    print(f"  dispatch stat: mode={oct(meta_st.mode)[2:]} uid={meta_st.uid} "
          f"gid={meta_st.gid} mtime={meta_st.modified}")

    print(f"=== ls /trello/workspaces/{first_ws}/boards/ ===")
    board_result = await ws.execute(f"ls /trello/workspaces/{first_ws}/boards/"
                                    )
    print(await board_result.stdout_str())

    # ── glob expansion: the workspace segment is the pattern, the
    # literal tail keeps walking (lists workspaces once, then filters).
    print("=== echo /trello/workspaces/*/boards (mid-path glob) ===")
    result = await ws.execute("echo /trello/workspaces/*/boards")
    glob_out = (await result.stdout_str()).strip()
    print(f"  {glob_out[:200]}")
    assert glob_out.endswith("/boards"), "mid-path glob did not expand"

    # A glob that matches nothing stays the literal word, so the
    # command reports it like GNU coreutils.
    print("=== cat /trello/workspaces/zz-none-*/workspace.json ===")
    result = await ws.execute("cat /trello/workspaces/zz-none-*/workspace.json"
                              )
    glob_err = (await result.stderr_str()).strip()
    print(f"  exit={result.exit_code}  {glob_err[:120]}")
    assert result.exit_code == 1 and "zz-none-*" in glob_err

    print(f"=== ls -l /trello/workspaces/{first_ws}/boards/ "
          "(mtime from dateLastActivity) ===")
    long_boards = await ws.execute(
        f"ls -l /trello/workspaces/{first_ws}/boards/")
    print(await long_boards.stdout_str())

    first_board = (await
                   board_result.stdout_str()).strip().splitlines()[0] if (
                       await board_result.stdout_str()).strip() else ""
    if not first_board:
        print("No boards available")
        return

    board_path = f"/trello/workspaces/{first_ws}/boards/{first_board}"

    print(f"=== cat {board_path}/board.json ===")
    result = await ws.execute(f"cat {board_path}/board.json")
    print(await result.stdout_str())
    board_payload = json.loads(await result.stdout_str())
    board_id = board_payload.get("board_id", "")

    print("=== trello board list ===")
    result = await ws.execute("trello board list")
    print(await result.stdout_str())

    print(f"=== trello board show {board_id} ===")
    result = await ws.execute(f"trello board show {board_id}")
    print(await result.stdout_str())

    print(f"=== ls {board_path}/members/ ===")
    member_result = await ws.execute(f"ls {board_path}/members/")
    print(await member_result.stdout_str())

    print(f"=== ls {board_path}/labels/ ===")
    label_result = await ws.execute(f"ls {board_path}/labels/")
    print(await label_result.stdout_str())

    print(f"=== ls {board_path}/lists/ ===")
    list_result = await ws.execute(f"ls {board_path}/lists/")
    print(await list_result.stdout_str())

    all_lists = (await list_result.stdout_str()).strip().splitlines()
    if not all_lists:
        print("No lists available")
        return

    first_card = ""
    list_path = ""
    list_id = ""
    for lst in all_lists:
        lp = f"{board_path}/lists/{lst}"
        r = await ws.execute(f"ls {lp}/cards/")
        cards = (await r.stdout_str()).strip().splitlines()
        if cards and cards[0]:
            list_path = lp
            first_card = cards[0]
            break

    print(f"=== cat {list_path}/list.json ===")
    result = await ws.execute(f"cat {list_path}/list.json")
    print(await result.stdout_str())

    list_payload = json.loads(await result.stdout_str())
    list_id = list_payload.get("list_id", "")

    print(f"=== ls {list_path}/cards/ ===")
    card_result = await ws.execute(f"ls {list_path}/cards/")
    print(await card_result.stdout_str())

    if not first_card:
        print("No cards available")
        return

    card_path = f"{list_path}/cards/{first_card}"

    print("=== cat card.json ===")
    result = await ws.execute(f"cat {card_path}/card.json")
    print(await result.stdout_str())

    card_payload = json.loads(await result.stdout_str())
    card_payload.get("card_id", "")

    print("=== head -n 3 comments.jsonl ===")
    result = await ws.execute(f"head -n 3 {card_path}/comments.jsonl")
    print(await result.stdout_str())

    print("=== tail -n 1 comments.jsonl ===")
    result = await ws.execute(f"tail -n 1 {card_path}/comments.jsonl")
    print(await result.stdout_str())

    print("=== wc -l comments.jsonl ===")
    result = await ws.execute(f"wc -l {card_path}/comments.jsonl")
    print(await result.stdout_str())

    print("=== stat card.json ===")
    result = await ws.execute(f"stat {card_path}/card.json")
    print(await result.stdout_str())

    print("=== jq .card_id card.json ===")
    result = await ws.execute(f'jq ".card_id" {card_path}/card.json')
    print(await result.stdout_str())

    print("=== jq .list_id card.json ===")
    result = await ws.execute(f'jq ".list_id" {card_path}/card.json')
    print(await result.stdout_str())

    print("=== tree -L 1 /trello/ ===")
    result = await ws.execute("tree -L 1 /trello/")
    print(await result.stdout_str())

    print(f"=== tree -L 1 {board_path}/ ===")
    result = await ws.execute(f"tree -L 1 {board_path}/")
    print(await result.stdout_str())

    print("=== find cards -name '*.json' ===")
    result = await ws.execute(
        f'find {list_path}/cards/ -name "*.json" | head -n 5')
    print(await result.stdout_str())

    # -path matches the display path; -size counts dirs and sizeless
    # rendered files as 0 (so +0c drops them, -1k keeps them).
    print("=== find board -path '*cards*' ===")
    result = await ws.execute(f'find {board_path}/ -path "*cards*" | head -n 5'
                              )
    print(await result.stdout_str())

    print("=== find board -maxdepth 1 -size +0c (dirs drop out) ===")
    result = await ws.execute(f"find {board_path}/ -maxdepth 1 -size +0c")
    print(f"  exit={result.exit_code}")
    print(await result.stdout_str())

    print("=== find board -type d (directory filter) ===")
    result = await ws.execute(f"find {board_path}/ -type d | head -n 5")
    print(await result.stdout_str())

    print("=== du -s board (walk fallback) ===")
    result = await ws.execute(f"du -s {board_path}/")
    print(await result.stdout_str())

    ws_path = f"/trello/workspaces/{first_ws}"
    print("=== grep -r wawa across workspace ===")
    result = await ws.execute(f"grep -r wawa {ws_path}/")
    print(await result.stdout_str())

    print("=== grep on card.json ===")
    result = await ws.execute(f"grep card_id {card_path}/card.json")
    print(await result.stdout_str())

    print("=== rg on board.json ===")
    result = await ws.execute(f"rg board_id {board_path}/board.json")
    print(await result.stdout_str())

    print("=== basename ===")
    result = await ws.execute(f"basename {card_path}/card.json")
    print(await result.stdout_str())

    print("=== dirname ===")
    result = await ws.execute(f"dirname {card_path}/card.json")
    print(await result.stdout_str())

    print("=== realpath ===")
    result = await ws.execute(f"realpath {card_path}/card.json")
    print(await result.stdout_str())

    print("=== trello card create ===")
    result = await ws.execute(f'trello card create --list_id {list_id}'
                              ' --name "Test card from MIRAGE"'
                              ' --desc "Created by example script"')
    print(await result.stdout_str())

    new_card = json.loads(await result.stdout_str())
    new_card_id = new_card.get("card_id", "")

    print("=== trello card update ===")
    result = await ws.execute(
        f'trello card update --card_id {new_card_id}'
        ' --name "Updated test card" --desc "Updated description"')
    print(await result.stdout_str())

    print("=== trello card move ===")
    result = await ws.execute(
        f"trello card move --card_id {new_card_id} --list_id {list_id}")
    print(await result.stdout_str())

    members = (await member_result.stdout_str()).strip().splitlines()
    if members:
        first_member_name = members[0]
        member_id = first_member_name.rsplit("__", 1)[-1].replace(".json", "")
        print("=== trello card assign ===")
        result = await ws.execute(f"trello card assign --card_id {new_card_id}"
                                  f" --member_id {member_id}")
        print(await result.stdout_str())

    print("=== trello card comment ===")
    result = await ws.execute(f'trello card comment --card_id {new_card_id}'
                              ' --text "Test comment from MIRAGE"')
    print(await result.stdout_str())

    comment_payload = json.loads(await result.stdout_str())
    comment_id = comment_payload.get("comment_id", "")

    print("=== trello card comment-update ===")
    result = await ws.execute(
        f"trello card comment-update --comment_id {comment_id}"
        f' --card_id {new_card_id} --text "Updated comment"')
    print(await result.stdout_str())

    labels = (await label_result.stdout_str()).strip().splitlines()
    if labels:
        first_label_name = labels[0]
        label_id = first_label_name.rsplit("__", 1)[-1].replace(".json", "")
        print("=== trello card label ===")
        result = await ws.execute(f"trello card label --card_id {new_card_id}"
                                  f" --label_id {label_id}")
        print(await result.stdout_str())

        print("=== trello card unlabel ===")
        result = await ws.execute(
            f"trello card unlabel --card_id {new_card_id}"
            f" --label_id {label_id}")
        print(await result.stdout_str())

    print("=== trello card update (archive) ===")
    result = await ws.execute(
        f"trello card update --card_id {new_card_id} --closed true")
    print(await result.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
