import { Provide, App } from '@midwayjs/core';
import { IMidwayApplication } from '@midwayjs/core';
import * as path from 'node:path';
import { pDataPath } from '../../../comm/path';
import { buildRuntimeStatus } from '../../../comm/runtime-state';
import { triggerGracefulShutdown } from '../../../comm/graceful-shutdown';
import { readRuntimeInfo } from '../../../comm/runtime-info';

@Provide()
export class RuntimeService {
  @App()
  app: IMidwayApplication;

  private stopHandler: (() => Promise<void>) | null = null;

  registerStopHandler(handler: () => Promise<void>) {
    this.stopHandler = handler;
  }

  async getRuntimeStatus() {
    const dataDir = pDataPath();
    const runtimeInfoPath = path.join(dataDir, 'runtime-info.json');
    const runtimeInfo = readRuntimeInfo(runtimeInfoPath);
    if (runtimeInfo) {
      return buildRuntimeStatus({
        pid: runtimeInfo.pid,
        ready: runtimeInfo.ready,
        startedAt: runtimeInfo.startedAt,
        port: runtimeInfo.port,
        controlBaseUrl: runtimeInfo.controlBaseUrl,
        dataDir: runtimeInfo.dataDir,
        logDir: runtimeInfo.logDir,
        configDir: runtimeInfo.configDir,
      });
    }

    const port = this.app.getConfig('koa.port');
    return buildRuntimeStatus({
      pid: process.pid,
      ready: (global as any).__NETA_RUNTIME_READY__ === true,
      startedAt: (global as any).__NETA_RUNTIME_STARTED_AT__ || new Date().toISOString(),
      port,
      controlBaseUrl: `http://127.0.0.1:${port}/app/base/runtime`,
      dataDir,
      logDir: path.join(dataDir, 'logs'),
      configDir: path.dirname(process.env.NETA_CONFIG_PATH || process.execPath),
    });
  }

  async stopRuntime() {
    if (this.stopHandler) {
      await this.stopHandler();
      return;
    }
    await triggerGracefulShutdown();
  }
}
