import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:yaml/yaml.dart';
import 'package:path/path.dart' as path;

/// CI/CD 환경과 로컬 환경에서 테스트 실행 시 설정을 관리하는 클래스
class TestConfig {
  static TestConfig? _instance;
  
  // 기본 설정값
  int asyncTimeout = 800;
  int testDelay = 100;
  int retryCount = 1;
  bool parallel = true;
  int memoryLimit = 0; // 0은 제한 없음
  int logLevel = 2;
  String isolationMode = 'normal';
  int timerCompletionWait = 500; // 테스트 종료 전 타이머 완료 대기 시간
  bool isCI = false;
  
  /// 싱글톤 인스턴스 반환
  static TestConfig get instance {
    _instance ??= TestConfig._internal();
    return _instance!;
  }
  
  TestConfig._internal() {
    _loadConfig();
  }
  
  /// 설정 파일 로드
  void _loadConfig() {
    try {
      // CI 환경 감지
      isCI = Platform.environment.containsKey('CI') || 
             Platform.environment.containsKey('GITHUB_ACTIONS') ||
             Platform.environment.containsKey('GITLAB_CI');
      
      if (kDebugMode) {
        print('TestConfig: CI 환경 감지 - $isCI');
      }
      
      // 설정 파일 경로
      final configPath = isCI 
          ? '.github/workflows/test_config.yaml'
          : 'test/test_config.yaml';
      
      // 프로젝트 루트 디렉토리 찾기
      String projectRoot = Directory.current.path;
      
      // pubspec.yaml이 있는 디렉토리를 찾을 때까지 상위 디렉토리로 이동
      while (!File(path.join(projectRoot, 'pubspec.yaml')).existsSync()) {
        final parent = Directory(projectRoot).parent;
        if (parent.path == projectRoot) {
          // 루트에 도달했는데도 pubspec.yaml을 찾지 못함
          break;
        }
        projectRoot = parent.path;
      }
      
      final configFile = File(path.join(projectRoot, configPath));
      
      if (configFile.existsSync()) {
        final yamlString = configFile.readAsStringSync();
        final yamlMap = loadYaml(yamlString) as Map;
        
        if (yamlMap.containsKey('test_settings')) {
          final settings = yamlMap['test_settings'] as Map;
          
          asyncTimeout = settings['async_timeout'] ?? asyncTimeout;
          testDelay = settings['test_delay'] ?? testDelay;
          retryCount = settings['retry_count'] ?? retryCount;
          parallel = settings['parallel'] ?? parallel;
          memoryLimit = settings['memory_limit'] ?? memoryLimit;
          logLevel = settings['log_level'] ?? logLevel;
          isolationMode = settings['isolation_mode'] ?? isolationMode;
          timerCompletionWait = settings['timer_completion_wait'] ?? timerCompletionWait;
          
          if (kDebugMode) {
            print('TestConfig: 설정 파일 로드 성공 - $configPath');
            print('TestConfig: asyncTimeout=$asyncTimeout, testDelay=$testDelay, retryCount=$retryCount');
          }
        }
      } else {
        if (kDebugMode) {
          print('TestConfig: 설정 파일 없음 - $configPath, 기본값 사용');
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print('TestConfig: 설정 로드 중 오류 - $e');
      }
    }
  }
  
  /// 테스트 환경에 맞는 비동기 타임아웃 값 반환
  Duration get asyncTimeoutDuration => Duration(milliseconds: asyncTimeout);
  
  /// 테스트 환경에 맞는 테스트 간 지연 시간 반환
  Duration get testDelayDuration => Duration(milliseconds: testDelay);
  
  /// 테스트 종료 전 타이머 완료 대기 시간 반환
  Duration get timerCompletionWaitDuration => Duration(milliseconds: timerCompletionWait);
  
  /// 테스트 환경에 맞는 로그 레벨 반환 (디버깅 상세도)
  bool get isVerboseLogging => logLevel >= 4;
  
  /// 테스트 격리 모드가 strict인지 확인
  bool get isStrictIsolation => isolationMode == 'strict';
}
