export type Player = {
    username: string;
    level: number;
};

export type Result<T> = { ok: true; value: T } | { ok: false; error: string };

export function playerFromUnknown(input: unknown): Result<Player> {
    if (input === undefined) {
        return { ok: false, error: "no input" };
    }
    if (input === null) {
        return { ok: false, error: "no input" };
    }
    if (typeof input === "string") {
        if (!/^[\d\w(:?\\\-)]+\-\d+$/.test(input)) {
            return { ok: false, error: "malformed player" };
        }
        const splits = input.split("-");
        let username = splits[0];
        if (username.includes("\\-")) {
            username = username.replaceAll("\\-", "-");
        }
        if (splits[1].startsWith("0") && splits[1].length >= 2) {
            return { ok: false, error: "malformed player" };
        }
        const level = parseInt(splits[1]);
        return { ok: true, value: { username, level } };
    } else if (typeof input === "object") {
        if (Object.keys(input).length < 2) {
            return { ok: false, error: "malformed player" };
        }
        if (Object.keys(input).length > 2) {
            return { ok: false, error: "too much information" };
        }
        if (!("username" in input && "level" in input)) {
            return { ok: false, error: "malformed player" };
        }
        if (typeof input.username !== "string") {
            return { ok: false, error: "malformed player" };
        }
        if (typeof input.level !== "number") {
            return { ok: false, error: "malformed player" };
        }
        const { username, level } = input;
        return { ok: true, value: { username, level } };
    } else {
        return { ok: false, error: "malformed player" };
    }
}