import datetime
import json
import os
import shutil
import sqlite3
import sys

DB = "/opt/friend-cluster/data/friend-cluster-v1.db"
INSTANCE = "friend-3f140466"
DEPLOYMENT = "deploy-adopted-c0e59158-8"
COMMAND = "cmd-b1449a7d-1"
now = datetime.datetime.now(datetime.timezone.utc).isoformat()

if not os.path.exists(DB):
    raise SystemExit(f"database missing: {DB}")

# Make a fresh rollback copy immediately before the transaction.
backup = DB + ".before-finalize-" + datetime.datetime.now().strftime("%Y%m%d%H%M%S")
shutil.copy2(DB, backup)
print("backup", backup)

con = sqlite3.connect(DB)
con.execute("PRAGMA foreign_keys=ON")
try:
    con.execute("BEGIN IMMEDIATE")
    fi = con.execute(
        "SELECT id,node_id,desired_run_state,process_state FROM friend_instances WHERE id=?",
        (INSTANCE,),
    ).fetchone()
    adopted = con.execute(
        "SELECT id,instance_id,status,node_id,allocation_id FROM instance_deployments WHERE id=?",
        (DEPLOYMENT,),
    ).fetchone()
    commands = con.execute(
        "SELECT id,action,status,instance_id FROM commands WHERE id=?",
        (COMMAND,),
    ).fetchone()
    allocation_count = con.execute(
        "SELECT COUNT(*) FROM allocations WHERE id IN (SELECT allocation_id FROM instance_deployments WHERE instance_id=? AND allocation_id<>'')",
        (INSTANCE,),
    ).fetchone()[0]
    print("precheck", json.dumps({"friend_instance": fi, "adopted_deployment": adopted, "command": commands, "allocation_count": allocation_count}))

    expected = (
        fi is not None
        and adopted is not None
        and adopted[1] == INSTANCE
        and adopted[2] == "deleting"
        and adopted[4] in (None, "")
        and commands is not None
        and commands[1] == "instance.decommission"
        and commands[2] == "queued"
        and commands[3] == INSTANCE
        and allocation_count == 1
    )
    # allocation_count includes the already-deleted automatic allocation. It is
    # not owned by the adopted deployment and must not be changed here.
    if not expected:
        raise RuntimeError("target state changed; refusing cleanup")

    for table in ("config_resources", "config_transactions", "extension_assignments"):
        cur = con.execute(f"DELETE FROM {table} WHERE instance_id=?", (INSTANCE,))
        print(table, cur.rowcount)

    cur = con.execute("DELETE FROM friend_instances WHERE id=?", (INSTANCE,))
    print("friend_instances", cur.rowcount)

    cur = con.execute(
        "UPDATE instance_deployments SET status='deleted',last_error='',updated_at=?,deleted_at=? WHERE id=? AND status='deleting'",
        (now, now, DEPLOYMENT),
    )
    print("adopted_deployment", cur.rowcount)

    cur = con.execute(
        "UPDATE commands SET status='succeeded',result=?,started_at=COALESCE(NULLIF(started_at,''),?),completed_at=? WHERE id=? AND action='instance.decommission' AND status='queued'",
        ("Friend already stopped and runtime/container absent; deletion finalized by Manager", now, now, COMMAND),
    )
    print("decommission_command", cur.rowcount)

    con.execute(
        "UPDATE enrollment_tokens SET enabled=0 WHERE id IN (SELECT enrollment_token_id FROM instance_deployments WHERE id=?)",
        (DEPLOYMENT,),
    )
    con.commit()
    print("COMMITTED")
except Exception:
    con.rollback()
    raise
finally:
    con.close()
