/**
 * Quality Assurance Service
 *
 * 중앙 품질 관리 서비스 (Orchestrator)
 *
 * 주요 기능:
 * - Collector, Evaluator, Recorder, Reporter 통합
 * - 품질 측정 실행 (수집 -> 평가 -> 기록)
 * - 리포트 생성
 * - 배치 작업 지원
 *
 * PRD FR-1.1: Orchestrator 역할 - 전체 품질 관리 플로우 조율
 */
import Database from 'better-sqlite3';
import { ensureQualityAssuranceSchema } from '../../../../shared/utils/ensure-quality-assurance-schema.js';
import { logger } from '../../../../shared/utils/logger.js';
import { QualityEvaluator } from './quality-evaluator.js';
import { QualityMetricsCollector } from './quality-metrics-collector.js';
import { QualityRecorder } from './quality-recorder.js';
import { QualityReporter } from './quality-reporter.js';
import { QualityThresholdManager } from './quality-threshold-manager.js';
/**
 * Quality Assurance Service
 *
 * PRD FR-1.1: Orchestrator 역할 - 전체 품질 관리 플로우 조율
 */
export class QualityAssuranceService {
    db;
    collector;
    evaluator;
    recorder;
    reporter;
    thresholdManager;
    constructor(db) {
        this.db = db;
        if (!db) {
            throw new Error('Database instance is required');
        }
        ensureQualityAssuranceSchema(db);
        this.collector = new QualityMetricsCollector(db);
        this.evaluator = new QualityEvaluator(db);
        this.recorder = new QualityRecorder(db);
        this.reporter = new QualityReporter(db);
        this.thresholdManager = new QualityThresholdManager(db);
    }
    /**
     * 품질 측정 실행
     *
     * 전체 플로우: 수집 -> 평가 -> 기록
     *
     * PRD FR-3.1: 배치 작업을 통해 주기적으로 품질을 측정해야 함
     *
     * @param options - 측정 옵션
     * @returns 측정 결과
     */
    async measureQuality(options = {}) {
        const { measurement_type = 'batch', context = 'default', namespaces, record = true } = options;
        const measuredAt = new Date().toISOString();
        logger.info(`품질 측정 시작: ${namespaces ? namespaces.join(', ') : 'all'} (${context})`, {
            measurement_type,
            context,
            namespaces
        });
        try {
            // 1. 품질 지표 수집
            let collectedMetricsList;
            if (namespaces && namespaces.length > 0) {
                // 특정 네임스페이스만 수집
                collectedMetricsList = await Promise.all(namespaces.map(ns => this.collector.collectMetricsByNamespace(ns, context)));
            }
            else {
                // 모든 네임스페이스 수집
                collectedMetricsList = await this.collector.collectAllMetrics(context);
            }
            // 2. 품질 평가
            const evaluationResults = await this.evaluator.evaluateAllMetrics(collectedMetricsList, context);
            // 3. 전체 상태 결정
            const overallStatus = this.evaluator.determineOverallStatus(evaluationResults);
            // 4. 경고 개수 계산
            const warningCount = evaluationResults.reduce((sum, result) => sum + result.warnings.length, 0);
            // 5. 측정 결과 기록 (옵션)
            let measurementIds = [];
            if (record) {
                measurementIds = await this.recorder.recordAllMeasurements(collectedMetricsList, evaluationResults, { measurement_type, context });
            }
            // 6. 경고 로그 기록
            if (warningCount > 0) {
                logger.warn(`품질 저하 감지: ${warningCount}개 경고`, {
                    measurement_type,
                    context,
                    namespaces: namespaces || 'all',
                    overall_status: overallStatus,
                    warning_count: warningCount
                });
            }
            const result = {
                measured_at: measuredAt,
                namespaces: namespaces || collectedMetricsList.map(m => m.namespace),
                collected_metrics: collectedMetricsList,
                evaluation_results: evaluationResults,
                measurement_ids: measurementIds,
                overall_status: overallStatus,
                warning_count: warningCount
            };
            logger.info(`품질 측정 완료: ${overallStatus} (${warningCount}개 경고)`, {
                measurement_type,
                context,
                namespaces: result.namespaces,
                overall_status: overallStatus,
                warning_count: warningCount,
                metrics_count: collectedMetricsList.length
            });
            return result;
        }
        catch (error) {
            logger.error('품질 측정 실패', {
                measurement_type,
                context,
                namespaces,
                error: error instanceof Error ? error.message : String(error)
            });
            throw error;
        }
    }
    /**
     * 품질 리포트 생성
     *
     * PRD FR-5.1: CLI 명령어로 품질 리포트를 생성할 수 있어야 함
     * PRD FR-5.2: HTTP API 엔드포인트로 품질 리포트를 조회할 수 있어야 함
     *
     * @param options - 리포트 옵션
     * @returns 리포트 문자열
     */
    async generateReport(options = {}) {
        return this.reporter.generateReport(options);
    }
    /**
     * 품질 리포트 데이터 조회
     *
     * @param options - 리포트 옵션
     * @returns 리포트 데이터
     */
    async getReportData(options = {}) {
        return this.reporter.collectReportData(options);
    }
    /**
     * 기본 품질 임계값 초기화
     *
     * PRD FR-4.1: 품질 임계값을 정의하고 관리할 수 있어야 함
     *
     * @param context - 컨텍스트 (기본값: 'default')
     * @param overwrite - 기존 임계값 덮어쓰기 여부 (기본값: false)
     * @returns 초기화된 임계값 개수
     */
    initializeDefaultThresholds(context = 'default', overwrite = false) {
        return this.thresholdManager.initializeDefaultThresholds(context, overwrite);
    }
    /**
     * 품질 임계값 조회
     *
     * @param namespace - 네임스페이스 필터 (선택적)
     * @param context - 컨텍스트 필터 (선택적)
     * @returns 임계값 목록
     */
    getThresholds(namespace, context) {
        return this.thresholdManager.getAllThresholds(namespace, context);
    }
    /**
     * 품질 임계값 설정
     *
     * @param namespace - 네임스페이스
     * @param key - 지표 키
     * @param threshold_value - 임계값
     * @param threshold_type - 임계값 타입 ('min' | 'max')
     * @param description - 설명 (선택적)
     * @param context - 컨텍스트 (기본값: 'default')
     * @returns 설정된 임계값
     */
    setThreshold(namespace, key, threshold_value, threshold_type, description, context = 'default') {
        return this.thresholdManager.setThreshold(namespace, key, { threshold_value, threshold_type, description }, context);
    }
    /**
     * 품질 임계값 삭제
     *
     * @param namespace - 네임스페이스
     * @param key - 지표 키
     * @param context - 컨텍스트 (기본값: 'default')
     * @returns 삭제 성공 여부
     */
    deleteThreshold(namespace, key, context = 'default') {
        return this.thresholdManager.deleteThreshold(namespace, key, context);
    }
    /**
     * 측정 이력 조회
     *
     * @param namespace - 네임스페이스 필터 (선택적)
     * @param context - 컨텍스트 필터 (선택적)
     * @param from - 시작 시간 (선택적)
     * @param to - 종료 시간 (선택적)
     * @param limit - 최대 개수 (기본값: 100)
     * @returns 측정 이력 목록
     */
    getMeasurementHistory(namespace, context, from, to, limit = 100) {
        return this.recorder.getMeasurementHistory(namespace, context, from, to, limit);
    }
    /**
     * 최신 품질 지표 조회
     *
     * @param namespace - 네임스페이스 필터 (선택적)
     * @param context - 컨텍스트 필터 (선택적)
     * @returns 최신 품질 지표 목록
     */
    getLatestMetrics(namespace, context) {
        return this.recorder.getLatestMetrics(namespace, context);
    }
    /**
     * 배치 작업용 품질 측정
     *
     * PRD FR-3.1: 배치 작업을 통해 주기적으로 품질을 측정해야 함
     *
     * @param context - 컨텍스트 (기본값: 'default')
     * @returns 측정 결과
     */
    async runBatchMeasurement(context = 'default') {
        return this.measureQuality({
            measurement_type: 'batch',
            context,
            record: true
        });
    }
    /**
     * 테스트용 품질 측정
     *
     * PRD FR-3.2: CI/CD 파이프라인에서 테스트 시 품질을 측정해야 함
     *
     * @param context - 컨텍스트 (기본값: 'ci')
     * @param namespaces - 측정할 네임스페이스 목록 (선택적)
     * @returns 측정 결과
     */
    async runTestMeasurement(context = 'ci', namespaces) {
        return this.measureQuality({
            measurement_type: 'test',
            context,
            namespaces,
            record: true
        });
    }
}
//# sourceMappingURL=quality-assurance-service.js.map