#! /usr/bin/env node

import fs from "fs";
import path from "path";
import { execSync } from "child_process";

require("dotenv").config({
    path: path.resolve(process.cwd(), ".env"),
});

import datasquirel from "../index";
import colors from "../console-colors";
import createDbFromSchema from "../package-shared/shell/createDbFromSchema";
import { DSQL_DatabaseSchemaType } from "../package-shared/types";

if (!fs.existsSync(path.resolve(process.cwd(), ".env"))) {
    console.log(".env file not found");
    process.exit();
}

const {
    DSQL_HOST,
    DSQL_USER,
    DSQL_PASS,
    DSQL_DB_NAME,
    DSQL_KEY,
    DSQL_REF_DB_NAME,
    DSQL_FULL_SYNC,
} = process.env;

if (!DSQL_HOST?.match(/./)) {
    console.log("DSQL_HOST is required in your `.env` file");
    process.exit();
}

if (!DSQL_USER?.match(/./)) {
    console.log("DSQL_USER is required in your `.env` file");
    process.exit();
}

if (!DSQL_PASS?.match(/./)) {
    console.log("DSQL_PASS is required in your `.env` file");
    process.exit();
}

const dbSchemaLocalFilePath = path.resolve(process.cwd(), "dsql.schema.json");

export default async function run() {
    let schemaData: any;

    if (DSQL_KEY && DSQL_REF_DB_NAME?.match(/./)) {
        const dbSchemaDataResponse = await datasquirel.getSchema({
            key: DSQL_KEY,
            database: DSQL_REF_DB_NAME || undefined,
        });

        if (
            !dbSchemaDataResponse.payload ||
            Array.isArray(dbSchemaDataResponse.payload)
        ) {
            console.log(
                "DSQL_KEY+DSQL_REF_DB_NAME => Error in fetching DB schema"
            );
            console.log(dbSchemaDataResponse);
            process.exit();
        }

        let fetchedDbSchemaObject =
            dbSchemaDataResponse.payload as DSQL_DatabaseSchemaType;
        if (DSQL_DB_NAME) fetchedDbSchemaObject.dbFullName = DSQL_DB_NAME;

        schemaData = [fetchedDbSchemaObject];
    } else if (DSQL_KEY) {
        const dbSchemaDataResponse = await datasquirel.getSchema({
            key: DSQL_KEY,
            database: DSQL_REF_DB_NAME || undefined,
        });

        if (
            !dbSchemaDataResponse.payload ||
            !Array.isArray(dbSchemaDataResponse.payload)
        ) {
            console.log("DSQL_KEY => Error in fetching DB schema");
            console.log(dbSchemaDataResponse);
            process.exit();
        }

        let fetchedDbSchemaObject = dbSchemaDataResponse.payload;
        // fetchedDbSchemaObject.forEach((db, index) => {
        //     db.dbFullName = db.dbFullName?.replace(/^datasquirel_user_\d+_/, "");
        // });

        schemaData = fetchedDbSchemaObject;
    } else if (fs.existsSync(dbSchemaLocalFilePath)) {
        schemaData = [
            JSON.parse(fs.readFileSync(dbSchemaLocalFilePath, "utf8")),
        ];
    } else {
        console.log(
            "No source for DB Schema. Please provide a local `dsql.schema.json` file, or provide `DSQL_KEY` and `DSQL_REF_DB_NAME` environment variables."
        );
        process.exit();
    }

    if (!schemaData) {
        console.log("No schema found");
        process.exit();
    }

    if (DSQL_FULL_SYNC?.match(/true/i)) {
        fs.writeFileSync(
            dbSchemaLocalFilePath,
            JSON.stringify(schemaData[0], null, 4),
            "utf8"
        );
    }

    console.log(
        ` - ${colors.FgBlue}Info:${colors.Reset} Now generating and mapping databases ...`
    );

    await createDbFromSchema({
        dbSchemaData: schemaData,
    });

    console.log(
        ` - ${colors.FgGreen}Success:${colors.Reset} Databases created Successfully!`
    );
}

let interval;

if (fs.existsSync(dbSchemaLocalFilePath) && !DSQL_KEY?.match(/....../)) {
    fs.watchFile(dbSchemaLocalFilePath, { interval: 1000 }, (curr, prev) => {
        console.log(
            ` - ${colors.FgBlue}Info:${colors.Reset} Syncing Databases Locally ...`
        );
        run();
    });
} else if (DSQL_KEY?.match(/....../)) {
    interval = setInterval(() => {
        console.log(
            ` - ${colors.FgMagenta}Info:${colors.Reset} Syncing Databases from the cloud ...`
        );
        run();
    }, 20000);
}

run();