// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
import 'package:skills_lint/skills_lint.dart';
import 'package:test/test.dart';

import 'check_backticks_relative_paths_rule.dart';

const String _configFileName = 'skills_lint.yaml';

Directory _findSkillsDir() {
  Directory dir = Directory.current;
  while (dir.path != dir.parent.path) {
    final skillsDir = Directory(path.join(dir.path, '.agents', 'skills'));
    if (skillsDir.existsSync()) {
      return skillsDir;
    }
    dir = dir.parent;
  }
  throw StateError(
    'Could not find .agents/skills directory starting from ${Directory.current.path}',
  );
}

void main() {
  final Directory skillsDir = _findSkillsDir();
  final String skillsDirectory = skillsDir.path;
  final Directory repoRoot = skillsDir.parent.parent;
  final String reidbakerSkillsDirectory = path.join(
    repoRoot.path,
    '.agents',
    'agents',
    'reidbaker-agent',
    'skills',
  );

  late Level oldLevel;
  StreamSubscription<LogRecord>? subscription;

  setUp(() {
    oldLevel = Logger.root.level;
    Logger.root.level = Level.ALL;
    subscription = Logger.root.onRecord.listen((record) {
      print(record.message);
    });
  });

  tearDown(() async {
    Logger.root.level = oldLevel;
    await subscription?.cancel();
  });

  test('Validate Flutter Skills', () async {
    final Configuration config = await ConfigParser.loadConfig(
      path: path.join(repoRoot.path, 'dev', 'tools', _configFileName),
    );
    final bool isValid = await validateSkills(
      skillDirPaths: [skillsDirectory, reidbakerSkillsDirectory],
      config: config,
    );
    expect(isValid, isTrue, reason: 'Skills validation failed. See above for details.');
  });

  test('Relative to root paths are not in backticks', () async {
    final valid2SegmentPaths = <String>{};

    final List<FileSystemEntity> entities = repoRoot.listSync();
    for (final entity in entities) {
      if (entity is Directory) {
        final String dirName = path.basename(entity.path);
        if (dirName.startsWith('.')) {
          continue;
        }

        final List<FileSystemEntity> subEntities = entity.listSync();
        for (final subEntity in subEntities) {
          if (subEntity is Directory) {
            final String subDirName = path.basename(subEntity.path);
            if (subDirName.startsWith('.')) {
              continue;
            }
            valid2SegmentPaths.add('$dirName/$subDirName');
          }
        }
      }
    }

    final bool isValid = await validateSkills(
      skillDirPaths: [skillsDirectory, reidbakerSkillsDirectory],
      customRules: [CheckBackticksRelativePathsRule(valid2SegmentPaths, repoRoot.path)],
      resolvedRuleConfigs: {
        'check-absolute-paths': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'check-relative-paths': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'check-trailing-whitespace': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'description-too-long': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'disallowed-field': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'invalid-skill-name': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
        'valid-yaml-metadata': const RuleConfigPatch(severity: AnalysisSeverity.disabled),
      },
    );
    expect(isValid, isTrue, reason: 'Skills validation failed. See above for details.');
  });

  test('CheckBackticksRelativePathsRule handles Windows paths', () async {
    final rule = CheckBackticksRelativePathsRule({'dev/tools'}, '/Users/reidbaker/flutter-work');

    final context = SkillContext(
      directory: Directory('/Users/reidbaker/flutter-work/.agents/skills/test-skill'),
      rawContent: r'Use `dev\tools\test.dart` to test.',
    );

    final List<ValidationError> errors = await rule.validate(context);

    expect(errors, hasLength(1));
    expect(errors.first.message, contains('[test.dart](../../../dev/tools/test.dart)'));
  });
}
