import 'dart:async';
import 'dart:io';

/// 스테이징 결재 더블(approval double) 연결 시 인증서 우회를 위한 HttpOverrides.
class _ApprovalStagingHttpOverrides extends HttpOverrides {
  _ApprovalStagingHttpOverrides(this._patterns);

  final List<_HostPattern> _patterns;

  bool _isAllowedHost(String host) {
    final normalized = host.trim().toLowerCase();
    if (normalized.isEmpty) {
      return false;
    }
    for (final pattern in _patterns) {
      if (pattern.matches(normalized)) {
        return true;
      }
    }
    return false;
  }

  @override
  HttpClient createHttpClient(SecurityContext? context) {
    final client = super.createHttpClient(context);
    client.badCertificateCallback = (cert, host, port) {
      // 허용된 호스트에 대해서만 자기서명 인증서를 허용한다.
      return _patterns.isNotEmpty && _isAllowedHost(host);
    };
    return client;
  }
}

/// 호스트 패턴(정확 일치 또는 서픽스 매칭)을 표현한다.
class _HostPattern {
  _HostPattern._(this.value, this.isSuffix);

  factory _HostPattern.parse(String raw) {
    final trimmed = raw.trim().toLowerCase();
    if (trimmed.startsWith('*.')) {
      return _HostPattern._(trimmed.substring(2), true);
    }
    if (trimmed.startsWith('.')) {
      return _HostPattern._(trimmed.substring(1), true);
    }
    return _HostPattern._(trimmed, false);
  }

  final String value;
  final bool isSuffix;

  bool get isValid => value.isNotEmpty;

  bool matches(String host) {
    if (!isValid) {
      return false;
    }
    if (isSuffix) {
      return host == value || host.endsWith('.$value');
    }
    return host == value;
  }
}

bool _parseBoolDynamic(String? raw) {
  if (raw == null) {
    return false;
  }
  switch (raw.trim().toLowerCase()) {
    case '1':
    case 'y':
    case 'yes':
    case 'true':
    case 'on':
      return true;
    default:
      return false;
  }
}

List<_HostPattern> _collectAllowedPatterns() {
  final env = Platform.environment;
  final tokens = <String>[];

  void addTokens(String? source) {
    if (source == null || source.trim().isEmpty) {
      return;
    }
    tokens.addAll(source.split(','));
  }

  addTokens(env['APPROVAL_DOUBLE_ALLOWED_HOSTS']);
  addTokens(
    const String.fromEnvironment(
      'APPROVAL_DOUBLE_ALLOWED_HOSTS',
      defaultValue: '',
    ),
  );

  final baseUrl =
      env['API_BASE_URL'] ??
      const String.fromEnvironment('API_BASE_URL', defaultValue: '');
  final uri = Uri.tryParse(baseUrl);
  if (uri != null && uri.host.isNotEmpty) {
    tokens.add(uri.host);
  }

  final patterns = <_HostPattern>[];
  for (final token in tokens) {
    final pattern = _HostPattern.parse(token);
    if (pattern.isValid) {
      patterns.add(pattern);
    }
  }
  return patterns;
}

/// Flutter 테스트 진입점.
///
/// - `USE_APPROVAL_STAGING_DOUBLE` 토글이 true일 때 HttpOverrides를 등록한다.
/// - `APPROVAL_DOUBLE_ALLOWED_HOSTS` 또는 `API_BASE_URL` 호스트를 인증 허용 목록에 추가한다.
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
  final runOverride =
      _parseBoolDynamic(Platform.environment['USE_APPROVAL_STAGING_DOUBLE']) ||
      const bool.fromEnvironment(
        'USE_APPROVAL_STAGING_DOUBLE',
        defaultValue: false,
      );

  HttpOverrides? previous;
  if (runOverride) {
    final patterns = _collectAllowedPatterns();
    if (patterns.isNotEmpty) {
      previous = HttpOverrides.current;
      HttpOverrides.global = _ApprovalStagingHttpOverrides(patterns);
    }
  }

  try {
    await testMain();
  } finally {
    if (runOverride) {
      HttpOverrides.global = previous;
    }
  }
}
