import fs from 'fs';
import dotenv from 'dotenv';
import { version, gitHead } from '@root/package.json';
import crypto from 'crypto';
import { execSync } from 'child_process';
import { env } from "./envConfig";

import devices from "./data/devices.json";

const getCommitHash = (): string => {
    // In production/Docker environments, use gitHead from package.json (set during npm publish)
    // Only try git command in development when gitHead might be outdated
    if (gitHead) {
        return gitHead.substring(0, 7);
    }

    // Fallback to git command (development environment)
    try {
        return execSync('git rev-parse --short HEAD', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
    } catch {
        return '';
    }
};
const customDevicesPath = './server/data/custom_devices.json';
const logsFolder = './logs';
dotenv.config();

// N-2 compatibility: SDKs from 2 minor versions back are supported
// Update this when releasing new minor versions
const CURRENT_VERSION = version;
const [major, minor] = CURRENT_VERSION.split('.').map(Number);
const minSupportedMinor = Math.max(0, minor - 2);
const MIN_SUPPORTED_SDK_VERSION = `${major}.${minSupportedMinor}.0`;

export const config = {
    version,
    commitHash: getCommitHash(),
    minSupportedSdkVersion: MIN_SUPPORTED_SDK_VERSION,
    apiVersion: '1',
    // this isn't used
    getDevices: async () => {
        if (fs.existsSync(customDevicesPath)) {
            return [...devices, ...(await import(customDevicesPath)).default];
        }
        return devices;
    },
    defaultImagesPath: env.SYNGRISI_IMAGES_PATH,
    domSnapshotsPath: env.SYNGRISI_DOM_SNAPSHOTS_PATH || env.SYNGRISI_IMAGES_PATH,
    connectionString: env.SYNGRISI_DB_URI || 'mongodb://127.0.0.1:27017/SyngrisiDb',
    host: env.SYNGRISI_HOSTNAME,
    port: env.SYNGRISI_APP_PORT || 3000,
    backupsFolder: './backups',
    enableHttpLogger: env.SYNGRISI_HTTP_LOG,
    httpLoggerFilePath: `${logsFolder}/http.log`,
    storeSessionKey: env.SYNGRISI_SESSION_STORE_KEY || crypto.randomBytes(64).toString('hex'),
    codeCoverage: env.SYNGRISI_COVERAGE,
    disableCors: env.SYNGRISI_DISABLE_DEV_CORS,
    fileUploadMaxSize: 50 * 1024 * 1024,
    adminDataJobsPath: env.SYNGRISI_ADMIN_DATA_JOBS_PATH,
    adminDataJobsTtlMs: env.SYNGRISI_ADMIN_DATA_JOBS_TTL_MS,
    adminDataMaxConcurrentJobs: env.SYNGRISI_ADMIN_DATA_MAX_CONCURRENT_JOBS,
    adminDataUploadMaxSize: env.SYNGRISI_ADMIN_DATA_UPLOAD_MAX_SIZE_MB * 1024 * 1024,
    testMode: env.SYNGRISI_TEST_MODE,
    jsonLimit: '50mb',
    tmpDir: env.SYNGRISI_TMP_DIR,
    helmet: {
        crossOriginEmbedderPolicy: false,
        crossOriginResourcePolicy: false,
        crossOriginOpenerPolicy: false,
        contentSecurityPolicy: {
            useDefaults: false,
            directives: {
                defaultSrc: ["'self'", "*", "'unsafe-inline'", "'unsafe-eval'", "data:", "blob:"],
                frameAncestors: ["'self'", "*"],
                frameSrc: ["'self'", "*"],
                scriptSrc: ["'self'", "*", "'unsafe-inline'", "'unsafe-eval'"],
                styleSrc: ["'self'", "*", "'unsafe-inline'"],
                imgSrc: ["'self'", "*", "data:", "blob:"],
                fontSrc: ["'self'", "*", "data:"],
                connectSrc: ["'self'", "*"],
                baseUri: ["'self'"],
                formAction: ["'self'"],
                objectSrc: ["'none'"],
                scriptSrcAttr: ["'none'"]
            },
        },
        hsts: false,
    },
    rateLimit: {
        windowMs: env.SYNGRISI_RATE_LIMIT_WINDOW_MS,
        max: env.SYNGRISI_RATE_LIMIT_MAX,
        standardHeaders: true,
        legacyHeaders: false,
    },
    authRateLimit: {
        windowMs: env.SYNGRISI_AUTH_RATE_LIMIT_WINDOW_MS,
        max: env.SYNGRISI_AUTH_RATE_LIMIT_MAX,
        standardHeaders: true,
        legacyHeaders: false,
    }
};

if (!fs.existsSync(config.defaultImagesPath)) {
    fs.mkdirSync(config.defaultImagesPath, { recursive: true });
}

if (config.domSnapshotsPath !== config.defaultImagesPath && !fs.existsSync(config.domSnapshotsPath)) {
    fs.mkdirSync(config.domSnapshotsPath, { recursive: true });
}

if (!fs.existsSync(config.adminDataJobsPath)) {
    fs.mkdirSync(config.adminDataJobsPath, { recursive: true });
}

if (!fs.existsSync(logsFolder)) {
    fs.mkdirSync(logsFolder, { recursive: true });
}

