import { MastodonStream } from "../channel.js";
import { isUserRelated } from "../../../../../misc/is-user-related.js";
import { isInstanceMuted } from "../../../../../misc/is-instance-muted.js";
import { NoteConverter } from "../../converters/note.js";
import { fetchMeta } from "../../../../../misc/fetch-meta.js";
import isQuote from "../../../../../misc/is-quote.js";
export class MastodonStreamPublic extends MastodonStream {
    static shouldShare = true;
    static requireCredential = false;
    mediaOnly;
    localOnly;
    remoteOnly;
    allowLocalOnly;
    constructor(connection, name){
        super(connection, name);
        this.mediaOnly = name.endsWith(":media");
        this.localOnly = name.startsWith("public:local");
        this.remoteOnly = name.startsWith("public:remote");
        this.allowLocalOnly = name.startsWith("public:allow_local_only");
        this.onNote = this.onNote.bind(this);
        this.onNoteEvent = this.onNoteEvent.bind(this);
    }
    async init() {
        const meta = await fetchMeta();
        if (meta.disableGlobalTimeline) {
            if (this.user == null || !(this.user.isAdmin || this.user.isModerator)) return;
        }
        this.subscriber.on("notesStream", this.onNote);
        this.subscriber.on("noteUpdatesStream", this.onNoteEvent);
    }
    async onNote(note) {
        if (!await this.shouldProcessNote(note)) return;
        const encoded = await NoteConverter.encodeEvent(note, this.user, 'public');
        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, 'public');
                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 (note.visibility !== "public") return false;
        if (note.channelId != null) return false;
        if (this.mediaOnly && note.fileIds.length < 1) return false;
        if (this.localOnly && note.userHost !== null) return false;
        if (this.remoteOnly && note.userHost === null) return false;
        if (note.localOnly && !this.allowLocalOnly && !this.localOnly) return false;
        if (isInstanceMuted(note, new Set(this.userProfile?.mutedInstances ?? []))) return false;
        if (isUserRelated(note, this.muting)) return false;
        if (isUserRelated(note, this.blocking)) return false;
        if (note.renoteId !== null && !isQuote(note) && this.renoteMuting.has(note.userId)) return false;
        return true;
    }
    dispose() {
        this.subscriber.off("notesStream", this.onNote);
        this.subscriber.off("noteUpdatesStream", this.onNoteEvent);
    }
}
