class Scope:
    def __init__(self, id, label="", children=None):
        self.id = id
        self.label = ""
        self.children = children or []

    def copy(self, prefix):
        return Scope(f"{prefix}:{self.id}")


BASE_SCOPES = [
    Scope(
        "profile", "Access profile data (e-mail, username, avatar, subsonic password…)"
    ),
    Scope("libraries", "Access uploads, libraries, and audio metadata"),
    Scope("edits", "Browse and submit edits on audio metadata"),
    Scope("follows", "Access library follows"),
    Scope("favorites", "Access favorites"),
    Scope("filters", "Access content filters"),
    Scope("listenings", "Access listening history"),
    Scope("radios", "Access radios"),
    Scope("playlists", "Access playlists"),
    Scope("notifications", "Access personal notifications"),
    Scope("security", "Access security settings"),
    Scope("reports", "Access reports"),
    Scope("plugins", "Access plugins"),
    # Privileged scopes that require specific user permissions
    Scope("instance:settings", "Access instance settings"),
    Scope("instance:users", "Access local user accounts"),
    Scope("instance:invitations", "Access invitations"),
    Scope("instance:edits", "Access instance metadata edits"),
    Scope(
        "instance:libraries", "Access instance uploads, libraries and audio metadata"
    ),
    Scope("instance:accounts", "Access instance federated accounts"),
    Scope("instance:domains", "Access instance domains"),
    Scope("instance:policies", "Access instance moderation policies"),
    Scope("instance:reports", "Access instance moderation reports"),
    Scope("instance:requests", "Access instance moderation requests"),
    Scope("instance:notes", "Access instance moderation notes"),
]
SCOPES = [
    Scope("read", children=[s.copy("read") for s in BASE_SCOPES]),
    Scope("write", children=[s.copy("write") for s in BASE_SCOPES]),
]


def flatten(*scopes):
    for scope in scopes:
        yield scope
        yield from flatten(*scope.children)


SCOPES_BY_ID = {s.id: s for s in flatten(*SCOPES)}

FEDERATION_REQUEST_SCOPES = {"read:libraries"}
ANONYMOUS_SCOPES = {
    "read:libraries",
    "read:playlists",
    "read:listenings",
    "read:favorites",
    "read:radios",
    "read:edits",
}

COMMON_SCOPES = ANONYMOUS_SCOPES | {
    "read:profile",
    "write:profile",
    "write:libraries",
    "write:playlists",
    "read:follows",
    "write:follows",
    "write:favorites",
    "read:notifications",
    "write:notifications",
    "write:radios",
    "write:edits",
    "read:filters",
    "write:filters",
    "read:reports",
    "write:reports",
    "write:listenings",
}

LOGGED_IN_SCOPES = COMMON_SCOPES | {
    "read:security",
    "write:security",
    "read:plugins",
    "write:plugins",
}

# We don't allow admin access for oauth apps yet
OAUTH_APP_SCOPES = COMMON_SCOPES


def get_from_permissions(**permissions):
    from funkwhale_api.users import models

    final = LOGGED_IN_SCOPES
    for permission_name, value in permissions.items():
        if not value:
            continue
        config = models.PERMISSIONS_CONFIGURATION[permission_name]
        final = final | config["scopes"]
    return final
