import { JsonStatus, Listing, SearchRedditNamesResponse, SearchSubredditsResponse, StickyResponse, SubmitTextResponse, SubredditAboutEditResponse, SubredditAboutResponse, SubredditAboutRulesResponse, SubredditAboutTrafficResponse, SubredditAddRemovalReasonResponse, SubredditAutocompleteResponse, SubredditGetRemovalReasonsResponse, SubredditPostRequirementsResponse, SubredditsSearchResponse, UploadSrImgResponse, UserSearchResponse, } from '@devvit/protos';
import { Empty } from '@devvit/protos/types/google/protobuf/empty.js';
import { StringValue } from '@devvit/protos/types/google/protobuf/wrappers.js';
import { Buffer } from '../../lib/Buffer.js';
import { findAndThrowRedditAPIError } from './errors.js';
import { RedditAPI } from './RedditAPI.js';
import { deepSnakeToCamel } from './snakeToCamel.js';
export class Subreddits extends RedditAPI {
    async AboutWhere(request, metadata) {
        const response = await this._fetch('AboutWhere', request, metadata);
        // Must wrap response.body in Buffer.from
        const body = JSON.parse(new TextDecoder().decode(Buffer.from(response.body)));
        findAndThrowRedditAPIError(response.status, body);
        // Children needs to be wrapped in the data field
        if (body.data != null) {
            body.data.children = body.data.children.map((child) => ({
                kind: 't2',
                data: child,
            }));
        }
        return Listing.fromJSON(deepSnakeToCamel(body));
    }
    async DeleteSrBanner(request, metadata) {
        const response = await this._fetch('DeleteSrBanner', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async DeleteSrHeader(request, metadata) {
        const response = await this._fetch('DeleteSrHeader', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async DeleteSrIcon(request, metadata) {
        const response = await this._fetch('DeleteSrIcon', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async DeleteSrImg(request, metadata) {
        const response = await this._fetch('DeleteSrImg', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SearchRedditNames(request, metadata) {
        const response = await this._fetch('SearchRedditNames', request, metadata);
        return SearchRedditNamesResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SearchSubreddits(request, metadata) {
        const response = await this._fetch('SearchSubreddits', request, metadata);
        return SearchSubredditsResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SiteAdmin(request, metadata) {
        const response = await this._fetch('SiteAdmin', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubmitText(request, metadata) {
        const response = await this._fetch('SubmitText', request, metadata);
        return SubmitTextResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAutocomplete(request, metadata) {
        const response = await this._fetch('SubredditAutocomplete', request, metadata);
        return SubredditAutocompleteResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditStylesheet(request, metadata) {
        const response = await this._fetch('SubredditStylesheet', request, metadata);
        return JsonStatus.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async Subscribe(request, metadata) {
        await this._fetch('Subscribe', request, metadata);
        return Empty.fromJSON({});
    }
    async UploadSrImg(request, metadata) {
        const response = await this._fetch('UploadSrImg', request, metadata);
        return UploadSrImgResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditPostRequirements(request, metadata) {
        const response = await this._fetch('SubredditPostRequirements', request, metadata);
        return SubredditPostRequirementsResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAbout(request, metadata) {
        const response = await this._fetch('SubredditAbout', request, metadata);
        return SubredditAboutResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAboutEdit(request, metadata) {
        const response = await this._fetch('SubredditAboutEdit', request, metadata);
        return SubredditAboutEditResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAboutRules(request, metadata) {
        const response = await this._fetch('SubredditAboutRules', request, metadata);
        return SubredditAboutRulesResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAboutTraffic(request, metadata) {
        const response = await this._fetch('SubredditAboutTraffic', request, metadata);
        return SubredditAboutTrafficResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async Sidebar(request, metadata) {
        const response = await this._fetch('Sidebar', request, metadata);
        // Must wrap response.body in Buffer.from
        return StringValue.fromJSON({ value: new TextDecoder().decode(Buffer.from(response.body)) });
    }
    async Sticky(request, metadata) {
        const response = await this._fetch('Sticky', request, metadata);
        return StickyResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditsMineWhere(request, metadata) {
        const response = await this._fetch('SubredditsMineWhere', request, metadata);
        return Listing.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditsSearch(request, metadata) {
        const response = await this._fetch('SubredditsSearch', request, metadata);
        // response.body.data.children could be subreddit or account types
        // so we push it into our custom types and drop the original children array.
        // Must wrap response.body in Buffer.from
        const body = JSON.parse(new TextDecoder().decode(Buffer.from(response.body)));
        findAndThrowRedditAPIError(response.status, body);
        const children = body?.data?.children || [];
        for (const child of children) {
            if (child.kind === 't5') {
                if (!body.data.children_subreddits) {
                    body.data.children_subreddits = [];
                }
                body.data.children_subreddits.push(child);
            }
            else if (child.kind === 't2') {
                if (!body.data.children_accounts) {
                    body.data.children_accounts = [];
                }
                body.data.children_accounts.push(child);
            }
        }
        delete body?.data?.children;
        return SubredditsSearchResponse.fromJSON(body);
    }
    async SubredditsWhere(request, metadata) {
        const response = await this._fetch('SubredditsWhere', request, metadata);
        return SubredditsSearchResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async UsersSearch(request, metadata) {
        const response = await this._fetch('UsersSearch', request, metadata);
        return UserSearchResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async UsersWhere(request, metadata) {
        const response = await this._fetch('UsersWhere', request, metadata);
        return SubredditsSearchResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditAddRemovalReason(request, metadata) {
        const response = await this._fetch('SubredditAddRemovalReason', request, metadata);
        return SubredditAddRemovalReasonResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
    async SubredditGetRemovalReasons(request, metadata) {
        const response = await this._fetch('SubredditGetRemovalReasons', request, metadata);
        return SubredditGetRemovalReasonsResponse.fromJSON(this._decodeAndValidateResponseJSON(response));
    }
}
