import { parse, ParseErrorCode } from '@sqs/jsonc-parser';
import { BehaviorSubject, combineLatest, ReplaySubject } from 'rxjs';
import { map } from 'rxjs/operators';
import { createAggregateError } from '../util/errors';
/**
 * Represents the configs from various subjects from GraphQL (user, orgs, and global).
 */
export const gqlConfigurationCascade = new ReplaySubject(1);
/**
 * Represents the client configuration (e.g. from the browser extension).
 */
export const clientConfiguration = new BehaviorSubject(undefined);
/**
 * Always represents the entire configuration cascade; i.e., it contains the
 * individual configs from the various config subjects (client, user, orgs, and
 * global).
 */
export const configurationCascade = combineLatest(gqlConfigurationCascade, clientConfiguration).pipe(map(([gqlCascade, clientContents]) => (Object.assign({}, gqlCascade, { subjects: [
        ...gqlCascade.subjects,
        ...(clientContents !== undefined
            ? [
                {
                    id: 'Client',
                    settingsURL: '',
                    viewerCanAdminister: true,
                    displayName: 'Client',
                    __typename: 'Client',
                    latestSettings: { id: 0, configuration: { contents: clientContents || '{}' } },
                },
            ]
            : []),
    ] }))));
/**
 * Always represents the latest merged configuration for the current user
 * or visitor. Callers should cast the value to their own configuration type.
 */
export const currentConfiguration = configurationCascade.pipe(map(cascade => parseJSON(cascade.merged.contents)));
/**
 * Parses the JSON input using the error-tolerant parser used for site config and settings.
 */
export function parseJSON(text) {
    const errors = [];
    const o = parse(text, errors, { allowTrailingComma: true, disallowComments: false });
    if (errors.length > 0) {
        throw createAggregateError(errors.map(v => (Object.assign({}, v, { code: ParseErrorCode[v.error], message: `Configuration parse error, code: ${v.error} (offset: ${v.offset}, length: ${v.length})` }))));
    }
    return o;
}
export function toGQLKeyPath(keyPath) {
    return keyPath.map(v => (typeof v === 'string' ? { property: v } : { index: v }));
}
//# sourceMappingURL=configuration.js.map