import { MastodonStream } from "../channel.js";
import { NoteConverter } from "../../converters/note.js";
import { UserListJoinings } from "../../../../../models/index.js";
export class MastodonStreamList extends MastodonStream {
    static shouldShare = false;
    static requireCredential = true;
    static requiredScopes = [
        'read:statuses'
    ];
    listId;
    listUsers = [];
    listUsersClock;
    constructor(connection, name, list){
        super(connection, name);
        this.listId = list;
        this.onNote = this.onNote.bind(this);
        this.onNoteEvent = this.onNoteEvent.bind(this);
        this.updateListUsers = this.updateListUsers.bind(this);
    }
    get user() {
        return this.connection.user;
    }
    async init() {
        if (!this.listId) return;
        this.subscriber.on("notesStream", this.onNote);
        this.subscriber.on("noteUpdatesStream", this.onNoteEvent);
        this.updateListUsers();
        this.listUsersClock = setInterval(this.updateListUsers, 5000);
    }
    async updateListUsers() {
        const users = await UserListJoinings.find({
            where: {
                userListId: this.listId
            },
            select: [
                "userId"
            ]
        });
        this.listUsers = users.map((x)=>x.userId);
    }
    async onNote(note) {
        if (!await this.shouldProcessNote(note)) return;
        const encoded = await NoteConverter.encodeEvent(note, this.user, 'home');
        this.connection.send(this.chName, "update", encoded);
    }
    async onNoteEvent(data) {
        const note = data.body;
        if (!await this.shouldProcessNote(note)) return;
        switch(data.type){
            case "updated":
                const encoded = await NoteConverter.encodeEvent(note, this.user, 'home');
                this.connection.send(this.chName, "status.update", encoded);
                break;
            case "deleted":
                this.connection.send(this.chName, "delete", note.id);
                break;
            default:
                break;
        }
    }
    async shouldProcessNote(note) {
        if (!this.listUsers.includes(note.userId)) return false;
        if (note.channelId) return false;
        if (note.renoteId !== null && !note.text && this.renoteMuting.has(note.userId)) return false;
        if (note.visibility === "specified") return !!note.visibleUserIds?.includes(this.user.id);
        if (note.visibility === "followers") return this.following.has(note.userId);
        return true;
    }
    dispose() {
        this.subscriber.off("notesStream", this.onNote);
        this.subscriber.off("noteUpdatesStream", this.onNoteEvent);
        clearInterval(this.listUsersClock);
    }
}
