/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2023 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

import type {Perms, UserPerms} from "@type/perms.js";
import {fetchWithToken, tokenStore} from "./repo";
import {PermsSchema, UserPermsSchema} from "@type/perms.js";
import {derived} from "svelte/store";

export class PermsRepo {
    constructor(private token: string) {
    }

    public async listPerms(): Promise<Perms> {
        const res = await fetchWithToken(this.token, "/perms");

        if (res.ok) {
            return PermsSchema.parse(await res.json());
        } else {
            throw new Error("Could not fetch perms: " + res.statusText);
        }
    }

    public async getPerms(userId: string): Promise<UserPerms> {
        return await fetchWithToken(this.token, `/perms/user/${userId}`).then(value => value.json()).then(UserPermsSchema.parse);
    }

    public async setPrefix(userId: string, prefix: string): Promise<void> {
        const res = await fetchWithToken(this.token, `/perms/user/${userId}/prefix/${prefix}`, {
            method: "PUT",
        });

        if (!res.ok) {
            throw new Error("Could not set prefix: " + res.statusText);
        }
    }

    public async addPerm(userId: string, perm: string): Promise<void> {
        const res = await fetchWithToken(this.token, `/perms/user/${userId}/${perm}`, {
            method: "PUT",
        });

        if (!res.ok) {
            throw new Error("Could not add perm: " + res.statusText);
        }
    }

    public async removePerm(userId: string, perm: string): Promise<void> {
        const res = await fetchWithToken(this.token, `/perms/user/${userId}/${perm}`, {
            method: "DELETE",
        });

        if (!res.ok) {
            throw new Error("Could not remove perm: " + res.statusText);
        }
    }
}

export const permsRepo = derived(tokenStore, ($token) => new PermsRepo($token));
