"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeExecutableSchemaId = exports.ApolloServerPluginSchemaReporting = void 0;
const os_1 = __importDefault(require("os"));
const uuid_1 = require("uuid");
const graphql_1 = require("graphql");
const schemaReporter_1 = require("./schemaReporter");
const createSHA_1 = __importDefault(require("../../utils/createSHA"));
function ApolloServerPluginSchemaReporting({ initialDelayMaxMs, overrideReportedSchema, endpointUrl, } = Object.create(null)) {
    const bootId = uuid_1.v4();
    return {
        __internal_plugin_id__() {
            return 'SchemaReporting';
        },
        serverWillStart({ apollo, schema, logger }) {
            return __awaiter(this, void 0, void 0, function* () {
                const { key, graphId } = apollo;
                if (!key) {
                    throw Error('To use ApolloServerPluginSchemaReporting, you must provide an Apollo API ' +
                        'key, via the APOLLO_KEY environment variable or via `new ApolloServer({apollo: {key})`');
                }
                if (!graphId) {
                    throw Error("To use ApolloServerPluginSchemaReporting, you must provide your graph's ID, " +
                        "either by using an API key starting with 'service:',  or by providing it explicitly via " +
                        'the APOLLO_GRAPH_ID environment variable or via `new ApolloServer({apollo: {graphId}})`');
                }
                if (overrideReportedSchema) {
                    try {
                        const validationErrors = graphql_1.validateSchema(graphql_1.buildSchema(overrideReportedSchema, { noLocation: true }));
                        if (validationErrors.length) {
                            throw new Error(validationErrors.map((error) => error.message).join('\n'));
                        }
                    }
                    catch (err) {
                        throw new Error('The schema provided to overrideReportedSchema failed to parse or ' +
                            `validate: ${err.message}`);
                    }
                }
                const executableSchema = overrideReportedSchema !== null && overrideReportedSchema !== void 0 ? overrideReportedSchema : graphql_1.printSchema(schema);
                const executableSchemaId = computeExecutableSchemaId(executableSchema);
                if (overrideReportedSchema !== undefined) {
                    logger.info('Apollo schema reporting: schema to report has been overridden');
                }
                if (endpointUrl !== undefined) {
                    logger.info(`Apollo schema reporting: schema reporting URL override: ${endpointUrl}`);
                }
                const serverInfo = {
                    bootId,
                    graphVariant: apollo.graphVariant,
                    platform: process.env.APOLLO_SERVER_PLATFORM || 'local',
                    runtimeVersion: `node ${process.version}`,
                    executableSchemaId: executableSchemaId,
                    userVersion: process.env.APOLLO_SERVER_USER_VERSION,
                    serverId: process.env.APOLLO_SERVER_ID || process.env.HOSTNAME || os_1.default.hostname(),
                    libraryVersion: `apollo-server-core@${require('../../../package.json').version}`,
                };
                logger.info('Apollo schema reporting starting! See your graph at ' +
                    `https://studio.apollographql.com/graph/${encodeURIComponent(graphId)}/?variant=${encodeURIComponent(apollo.graphVariant)} with server info ${JSON.stringify(serverInfo)}`);
                const schemaReporter = new schemaReporter_1.SchemaReporter({
                    serverInfo,
                    schemaSdl: executableSchema,
                    apiKey: key,
                    endpointUrl,
                    logger,
                    initialReportingDelayInMs: Math.floor(Math.random() * (initialDelayMaxMs !== null && initialDelayMaxMs !== void 0 ? initialDelayMaxMs : 10000)),
                    fallbackReportingDelayInMs: 20000,
                });
                schemaReporter.start();
                return {
                    serverWillStop() {
                        return __awaiter(this, void 0, void 0, function* () {
                            schemaReporter.stop();
                        });
                    },
                };
            });
        },
    };
}
exports.ApolloServerPluginSchemaReporting = ApolloServerPluginSchemaReporting;
function computeExecutableSchemaId(schema) {
    return createSHA_1.default('sha256').update(schema).digest('hex');
}
exports.computeExecutableSchemaId = computeExecutableSchemaId;
//# sourceMappingURL=index.js.map