#!/usr/bin/python3

import json
import requests

# Change these configs
TOKEN = "misskey-api-token"
INSTANCE = "https://your-instance.com"


def post(path, body):
    """Sends a post request to the Misskey instance."""
    return requests.post(
        f"{INSTANCE}/api{path}",
        headers={
            "Authorization": f"Bearer {TOKEN}",
            "Content-Type": "application/json",
        },
        data=json.dumps(body),
        timeout=10,
    )


def fetch_notes(user_id, until_id=None):
    """Fetches all notes from a user."""
    if until_id:
        notes = post(
            "/users/notes",
            {
                "userId": user_id,
                "withFiles": False,
                "withReplies": True,
                "withChannelNotes": True,
                "limit": 100,
                "untilId": until_id
            },
        )
    else:
        notes = post(
            "/users/notes",
            {
                "userId": user_id,
                "withFiles": False,
                "withReplies": True,
                "withChannelNotes": True,
                "limit": 100
            },
        )
    return notes.json()


def fetch_users(target_instance, until_id=None):
    """Gets all users for a given Misskey instance."""
    if until_id:
        users = post(
            "/federation/users",
            {"limit": 100, "host": target_instance, "untilId": until_id},
        )
    else:
        users = post("/federation/users", {"limit": 100, "host": target_instance})
    return users.json()


def destroy(target_instance):
    """Destroys all accounts on the given Misskey instance."""
    users = fetch_users(target_instance)

    while users:
        for user in users:
            destroy_notes(user['id'])
            r1 = post("/admin/delete-account", {"userId": user['id']})
            r2 = post("/admin/delete-all-files-of-a-user", {"userId": user['id']})
            if r1.status_code == 204 and r2.status_code == 204:
                print(f"Deleted @{user['username']}@{user['host']}")
            else:
                print(f"Failed to delete @{user['username']}@{user['host']}!!!!!")

        users = fetch_users(target_instance, users[-1]['id'])


def destroy_notes(user_id):
    """Destroys all accounts on the given Misskey instance."""
    notes = fetch_notes(user_id)

    while notes:
        for note in notes:
            r = post("/notes/delete", {"noteId": note['id']})
            if r.status_code == 204:
                print(f"Deleted {print_name(note)}: {print_note(note)}")
            else:
                print(f"Could not delete {print_name(note)}: {print_note(note)}")

        notes = fetch_notes(user_id, notes[-1]['id'])

def print_note(note):
    if note.get('renote') and note['renote'].get('reactions'):
        return "Reaction"
    elif note.get('renote'):
        return f"Renote {print_note(note['renote'])}"
    elif note.get('files') or note.get('fileIds'):
        return "File"
    elif note.get('reactions'):
        return "Reaction"
    else:
        if note['text'] is None:
            print(note)
        return truncate_text(note['text'])

def print_name(note):
    return f"@{note['user']['username']}@{note['user']['host']}"

def truncate_text(text):
    if text is None:
        return "None"
    else:
        return text[:75].replace("\n", " ")


destroy("instance-to-destroy.com")