import grabHostNames from "../utils/grab-host-names";
import {
    DSQL_DatabaseSchemaType,
    DSQL_FieldSchemaType,
    DSQL_TableSchemaType,
    GetSchemaAPIParam,
    GetSchemaRequestQuery,
} from "../types";

type GetSchemaReturn = {
    success: boolean;
    payload?:
        | DSQL_DatabaseSchemaType
        | DSQL_TableSchemaType
        | DSQL_FieldSchemaType
        | null;
};

/**
 * # Get Schema for Database, table, or field *
 */
export default async function getSchema({
    key,
    database,
    field,
    table,
    user_id,
    env,
}: GetSchemaAPIParam): Promise<GetSchemaReturn> {
    const grabedHostNames = grabHostNames({ env });
    const { host, port, scheme } = grabedHostNames;

    /**
     * Make https request
     *
     * @description make a request to datasquirel.com
     */
    const httpResponse = await new Promise((resolve, reject) => {
        const queryObject: GetSchemaRequestQuery = { database, field, table };
        let query = Object.keys(queryObject)
            .filter((k) => queryObject[k as keyof GetSchemaRequestQuery])
            .map((k) => `${k}=${queryObject[k as keyof GetSchemaRequestQuery]}`)
            .join("&");

        scheme
            .request(
                {
                    method: "GET",
                    headers: {
                        "Content-Type": "application/json",
                        Authorization:
                            key ||
                            process.env.DSQL_FULL_ACCESS_API_KEY ||
                            process.env.DSQL_API_KEY,
                    },
                    port,
                    hostname: host,
                    path:
                        `/api/query/${
                            user_id || grabedHostNames.user_id
                        }/get-schema` + (query?.match(/./) ? `?${query}` : ""),
                },

                /**
                 * Callback Function
                 *
                 * @description https request callback
                 */
                (response) => {
                    var str = "";

                    response.on("data", function (chunk) {
                        str += chunk;
                    });

                    response.on("end", function () {
                        resolve(
                            JSON.parse(str) as
                                | DSQL_DatabaseSchemaType
                                | DSQL_TableSchemaType
                                | DSQL_FieldSchemaType
                        );
                    });

                    response.on("error", (err) => {
                        resolve(null);
                    });
                }
            )
            .end();
    });

    return httpResponse as GetSchemaReturn;
}