// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. 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:io';

import 'package:ffigen/src/code_generator.dart';
import 'package:ffigen/src/config_provider/config.dart';
import 'package:ffigen/src/strings.dart' as strings;
import 'package:logging/logging.dart';
import 'package:package_config/package_config_types.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:yaml/yaml.dart' as yaml;

extension LibraryTestExt on Library {
  /// Get a [Binding]'s generated string with a given name.
  String getBindingAsString(String name) {
    try {
      final b = bindings.firstWhere((element) => element.name == name);
      return b.toBindingString(writer).string;
    } catch (e) {
      throw NotFoundException("Binding '$name' not found.");
    }
  }

  /// Get a [Binding] with a given name.
  Binding getBinding(String name) {
    try {
      final b = bindings.firstWhere((element) => element.name == name);
      return b;
    } catch (e) {
      throw NotFoundException("Binding '$name' not found.");
    }
  }
}

/// Check whether a file generated by test/setup.dart exists and throw a helpful
/// exception if it does not.
void verifySetupFile(File file) {
  if (!file.existsSync()) {
    throw NotFoundException("The file ${file.path} does not exist.\n\n"
        "You may need to run: dart run test/setup.dart\n");
  }
}

// Remove '\r' for Windows compatibility, then apply user's normalizer.
String _normalizeGeneratedCode(
    String generated, String Function(String)? codeNormalizer) {
  final noCR = generated.replaceAll('\r', '').replaceAll(RegExp(r'\n+'), '\n');
  if (codeNormalizer == null) return noCR;
  return codeNormalizer(noCR);
}

/// Generates actual file using library and tests using [expect] with expected.
///
/// This will not delete the actual debug file incase [expect] throws an error.
void matchLibraryWithExpected(
    Library library, String pathForActual, List<String> pathToExpected,
    {String Function(String)? codeNormalizer}) {
  _matchFileWithExpected(
    library: library,
    pathForActual: pathForActual,
    pathToExpected: pathToExpected,
    fileWriter: ({required Library library, required File file}) =>
        library.generateFile(file),
    codeNormalizer: codeNormalizer,
  );
}

/// Generates actual file using library and tests using [expect] with expected.
///
/// This will not delete the actual debug file incase [expect] throws an error.
void matchLibrarySymbolFileWithExpected(Library library, String pathForActual,
    List<String> pathToExpected, String importPath) {
  _matchFileWithExpected(
      library: library,
      pathForActual: pathForActual,
      pathToExpected: pathToExpected,
      fileWriter: ({required Library library, required File file}) {
        if (!library.writer.canGenerateSymbolOutput) library.generate();
        library.generateSymbolOutputFile(file, importPath);
      });
}

/// Generates actual file using library and tests using [expect] with expected.
///
/// This will not delete the actual debug file incase [expect] throws an error.
void _matchFileWithExpected({
  required Library library,
  required String pathForActual,
  required List<String> pathToExpected,
  required void Function({required Library library, required File file})
      fileWriter,
  String Function(String)? codeNormalizer,
}) {
  final file = File(
    path.join(strings.tmpDir, pathForActual),
  );
  fileWriter(library: library, file: file);
  try {
    final actual =
        _normalizeGeneratedCode(file.readAsStringSync(), codeNormalizer);
    final expected = _normalizeGeneratedCode(
        File(path.joinAll(pathToExpected)).readAsStringSync(), codeNormalizer);
    expect(actual, expected);
    if (file.existsSync()) {
      file.delete();
    }
  } catch (e) {
    print('Failed test: Debug generated file: ${file.absolute.path}');
    rethrow;
  }
}

class NotFoundException implements Exception {
  final String message;
  NotFoundException(this.message);

  @override
  String toString() {
    return message;
  }
}

void logWarnings([Level level = Level.WARNING]) {
  Logger.root.level = level;
  Logger.root.onRecord.listen((record) {
    print('${record.level.name.padRight(8)}: ${record.message}');
  });
}

void logWarningsToArray(List<String> logArr, [Level level = Level.WARNING]) {
  Logger.root.level = level;
  Logger.root.onRecord.listen((record) {
    logArr.add('${record.level.name.padRight(8)}: ${record.message}');
  });
}

Config testConfig(String yamlBody, {String? filename}) {
  return Config.fromYaml(
    yaml.loadYaml(yamlBody) as yaml.YamlMap,
    filename: filename,
    packageConfig: PackageConfig([
      Package(
        'shared_bindings',
        Uri.file(path.join(path.current, 'example', 'shared_bindings', 'lib/')),
      ),
    ]),
  );
}

Config testConfigFromPath(String path) {
  final file = File(path);
  final yamlBody = file.readAsStringSync();
  return testConfig(yamlBody, filename: path);
}

T withChDir<T>(String path, T Function() inner) {
  final oldDir = Directory.current;
  Directory.current = File(path).parent;

  late T result;

  try {
    result = inner();
  } finally {
    Directory.current = oldDir;
  }

  return result;
}
