"use strict";
// Check if ~/.apptile-cli exists. If it doesn't create it and add workspaces table.
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteMetroProc = deleteMetroProc;
exports.getCurrentMetroProc = getCurrentMetroProc;
exports.createMetroProc = createMetroProc;
exports.createWorkspace = createWorkspace;
exports.deleteLink = deleteLink;
exports.getWorkspaces = getWorkspaces;
exports.getWorkspace = getWorkspace;
exports.getWorkspaceByLocation = getWorkspaceByLocation;
exports.insertOrUpdateOpenapp = insertOrUpdateOpenapp;
exports.getOpenApp = getOpenApp;
exports.closeAppByLocation = closeAppByLocation;
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
const os_1 = __importDefault(require("os"));
const path_1 = __importDefault(require("path"));
const fs_1 = require("fs");
const types_1 = require("../ui/src/types");
const homeDir = os_1.default.homedir();
try {
    (0, fs_1.mkdirSync)(path_1.default.resolve(homeDir, '.apptile-cli'));
}
catch (err) {
    if ((err === null || err === void 0 ? void 0 : err.code) === 'EEXIST') {
        console.log("config folder already exists");
    }
    else {
        throw err;
    }
}
const dbFilePath = path_1.default.resolve(homeDir, '.apptile-cli/db.sqlite');
const db = new better_sqlite3_1.default(dbFilePath, { verbose: console.log });
// migrations
db.exec(`CREATE TABLE IF NOT EXISTS workspaces (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    location VARCHAR(255) NOT NULL
  );
`);
db.exec(`
  CREATE TABLE IF NOT EXISTS openapps (
    appId VARCHAR(255) PRIMARY KEY,
    workspaceId INTEGER,
    repoPath VARCHAR(255)
  );
`);
db.exec(`CREATE TABLE IF NOT EXISTS metro (
    pid INTEGER PRIMARY KEY,
    repoPath VARCHAR(255)
  );
`);
function narrowMetroProc(raw) {
    try {
        return (typeof raw.pid === "number") &&
            (typeof raw.repoPath === "string");
    }
    catch (err) {
        console.error("Failed to narrow metro proc");
        return false;
    }
}
function narrowMetroProcArray(raw) {
    try {
        let result = true;
        for (let i = 0; i < raw.length; ++i) {
            result = result && narrowMetroProc(raw[i]);
        }
        return result;
    }
    catch (err) {
        console.error("Failed to validate metroProc array");
        return false;
    }
}
const delMetroProc = db.prepare(`DELETE FROM metro WHERE repoPath=?`);
function deleteMetroProc(repoPath) {
    delMetroProc.run(repoPath);
}
const selectMetroProc = db.prepare(`SELECT * FROM metro`);
function getCurrentMetroProc() {
    let procs = selectMetroProc.all();
    if (narrowMetroProcArray(procs)) {
        return procs;
    }
    else {
        return null;
    }
}
const insertMetroProc = db.prepare(`INSERT INTO metro (pid, repoPath) VALUES (?,?)`);
function createMetroProc(pid, fullPath) {
    insertMetroProc.run(pid.toFixed(0), fullPath);
}
const insertWorkspace = db.prepare(`INSERT INTO workspaces (location)
               VALUES (?)`);
function createWorkspace(location) {
    try {
        insertWorkspace.run(location);
    }
    catch (err) {
        console.error("Failed to create link", err);
    }
}
const removeWorkspace = db.prepare(`DELETE FROM workspaces WHERE id = ?`);
function deleteLink(id) {
    removeWorkspace.run(id);
}
const getAllWorkspaces = db.prepare(`SELECT * FROM workspaces`);
function getWorkspaces() {
    const workspaces = getAllWorkspaces.all();
    if (types_1.DataBase.narrowWorkspaceArray(workspaces)) {
        return workspaces;
    }
    else {
        console.error("Invalid link found in table", workspaces);
        return null;
    }
}
const findWorkspace = db.prepare(`SELECT * FROM workspaces WHERE id = ?`);
function getWorkspace(id) {
    const workspace = findWorkspace.get(id.toFixed(0));
    if (types_1.DataBase.narrowWorkspace(workspace)) {
        return workspace;
    }
    else {
        console.error("Invalid workspace found in table", workspace);
        return null;
    }
}
const findWorkspaceByLocation = db.prepare(`SELECT * FROM workspaces WHERE location = ?`);
function getWorkspaceByLocation(location) {
    const workspace = findWorkspaceByLocation.get(location);
    if (types_1.DataBase.narrowWorkspace(workspace)) {
        return workspace;
    }
    else {
        console.error("Invalid workspace found in table", workspace);
        return null;
    }
}
function narrowOpenedApp(result) {
    return ((result) &&
        (typeof (result.appId) === "string") &&
        (typeof (result.workspaceId === "string")) &&
        (typeof (result.repoPath) === "string") &&
        (!!result.repoPath));
}
const insertOrUpdateOpenapps = db.prepare(`INSERT INTO openapps (workspaceId, appId, repoPath) 
  VALUES (?, ?, ?)
  ON CONFLICT(appId)
  DO UPDATE SET 
    workspaceId = excluded.workspaceId,
    repoPath = excluded.repoPath
  `);
function insertOrUpdateOpenapp(workspaceId, appId, repoPath) {
    insertOrUpdateOpenapps.run(workspaceId, appId, repoPath);
}
const findOpenApp = db.prepare(`SELECT * FROM openapps WHERE appId = ?`);
function getOpenApp(appId) {
    const openedAppEntry = findOpenApp.get(appId);
    if (narrowOpenedApp(openedAppEntry)) {
        return openedAppEntry;
    }
    else {
        return null;
    }
}
const deleteAppByLocationQuery = db.prepare(`DELETE FROM openapps WHERE repoPath = ?`);
function closeAppByLocation(repoPath) {
    return deleteAppByLocationQuery.run(repoPath);
}
exports.default = db;
