// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
import 'package:yaml_edit/src/utils.dart';
import 'package:yaml_edit/yaml_edit.dart';

import 'test_utils.dart';

/// Interface for creating golden Test cases
class TestCases {
  final List<_TestCase> testCases;

  /// Creates a [TestCases] object based on test directory and golden directory
  /// path.
  static Future<TestCases> getTestCases(Uri testDirUri, Uri goldDirUri) async {
    final testDir = Directory.fromUri(testDirUri);

    if (!testDir.existsSync()) return TestCases([]);

    /// Recursively grab all the files in the testing directory.
    return TestCases(await testDir
        .list(recursive: true, followLinks: false)
        .where((entity) => entity.path.endsWith('.test'))
        .map((entity) => entity.uri)
        .map((inputUri) {
      final inputWithoutExtension =
          p.basenameWithoutExtension(inputUri.toFilePath());
      final goldenUri = goldDirUri.resolve('./$inputWithoutExtension.golden');

      return _TestCase(inputUri, goldenUri);
    }).toList());
  }

  /// Tests all the [_TestCase]s if the golden files exist, create the golden
  /// files otherwise.
  void test() {
    var tested = 0;
    var created = 0;

    for (final testCase in testCases) {
      testCase.testOrCreate();
      if (testCase.state == _TestCaseStates.testedGoldenFile) {
        tested++;
      } else if (testCase.state == _TestCaseStates.createdGoldenFile) {
        created++;
      }
    }

    print(
        'Successfully tested $tested inputs against golden files, created $created golden files');
  }

  TestCases(this.testCases);

  int get length => testCases.length;
}

/// Enum representing the different states of [_TestCase]s.
enum _TestCaseStates { initialized, createdGoldenFile, testedGoldenFile }

/// Interface for a golden test case. Handles the logic for test conduct/golden
/// test update accordingly.
class _TestCase {
  final Uri inputUri;
  final Uri goldenUri;
  final List<String> states = [];

  late String info;
  late YamlEditor yamlBuilder;
  late List<_YamlModification> modifications;

  String inputLineEndings = '\n';

  _TestCaseStates state = _TestCaseStates.initialized;

  _TestCase(this.inputUri, this.goldenUri) {
    final inputFile = File.fromUri(inputUri);
    if (!inputFile.existsSync()) {
      throw Exception('Input File does not exist!');
    }

    _initialize(inputFile);
  }

  /// Initializes the [_TestCase] by reading the corresponding [inputFile] and
  /// parsing the different portions, and then running the input yaml against
  /// the specified modifications.
  ///
  /// Precondition: [inputFile] must exist, and inputs must be well-formatted.
  void _initialize(File inputFile) {
    final input = inputFile.readAsStringSync();

    final inputLineEndings = getLineEnding(input);
    final inputElements = input.split('---$inputLineEndings');

    if (inputElements.length != 3) {
      throw AssertionError('File ${inputFile.path} is not properly formatted.');
    }

    info = inputElements[0];
    yamlBuilder = YamlEditor(inputElements[1]);
    final rawModifications = _getValueFromYamlNode(loadYaml(inputElements[2]));
    modifications = _parseModifications(rawModifications);

    /// Adds the initial state as well, so we can check that the simplest
    /// parse -> immediately dump does not affect the string.
    states.add(yamlBuilder.toString());

    _performModifications();
  }

  void _performModifications() {
    for (final mod in modifications) {
      _performModification(mod);
      states.add(yamlBuilder.toString());
    }
  }

  void _performModification(_YamlModification mod) {
    switch (mod.method) {
      case YamlModificationMethod.update:
        yamlBuilder.update(mod.path, mod.value);
        return;
      case YamlModificationMethod.remove:
        yamlBuilder.remove(mod.path);
        return;
      case YamlModificationMethod.appendTo:
        yamlBuilder.appendToList(mod.path, mod.value);
        return;
      case YamlModificationMethod.prependTo:
        yamlBuilder.prependToList(mod.path, mod.value);
        return;
      case YamlModificationMethod.insert:
        yamlBuilder.insertIntoList(mod.path, mod.index, mod.value);
        return;
      case YamlModificationMethod.splice:
        yamlBuilder.spliceList(mod.path, mod.index, mod.deleteCount, mod.value);
        return;
    }
  }

  void testOrCreate() {
    final goldenFile = File.fromUri(goldenUri);
    if (!goldenFile.existsSync()) {
      createGoldenFile(goldenFile);
    } else {
      testGoldenFile(goldenFile);
    }
  }

  void createGoldenFile(File goldenFile) {
    /// Assumes user wants the golden file to have the same line endings as
    /// the input file.
    final goldenOutput = states.join('---$inputLineEndings');

    goldenFile.writeAsStringSync(goldenOutput);
    state = _TestCaseStates.createdGoldenFile;
  }

  /// Tests the golden file. Ensures that the number of states are the same, and
  /// that the individual states are the same.
  void testGoldenFile(File goldenFile) {
    final inputFileName = p.basename(inputUri.toFilePath());
    final golden = goldenFile.readAsStringSync();
    final goldenStates = golden.split('---${getLineEnding(golden)}');

    group('testing $inputFileName - input and golden files have', () {
      test('same number of states', () {
        expect(states.length, equals(goldenStates.length));
      });

      for (var i = 0; i < states.length; i++) {
        test('same state $i', () {
          expect(states[i], equals(goldenStates[i]));
        });
      }
    });

    state = _TestCaseStates.testedGoldenFile;
  }
}

/// Converts [yamlList] into a Dart list.
List _getValueFromYamlList(YamlList yamlList) {
  return yamlList.value.map((n) {
    if (n is YamlNode) return _getValueFromYamlNode(n);
    return n;
  }).toList();
}

/// Converts [yamlMap] into a Dart Map.
Map _getValueFromYamlMap(YamlMap yamlMap) {
  final keys = yamlMap.keys;
  final result = {};
  for (final key in keys) {
    final value = yamlMap[key];

    if (value is YamlNode) {
      result[key] = _getValueFromYamlNode(value);
    } else {
      result[key] = value;
    }
  }

  return result;
}

/// Converts a [YamlNode] into a Dart object.
dynamic _getValueFromYamlNode(YamlNode node) {
  if (node is YamlList) {
    return _getValueFromYamlList(node);
  }
  if (node is YamlMap) {
    return _getValueFromYamlMap(node);
  }
  return node.value;
}

/// Converts the list of modifications from the raw input to [_YamlModification]
/// objects.
List<_YamlModification> _parseModifications(List<dynamic> modifications) {
  return modifications.map((mod) {
    Object? value;
    var index = 0;
    var deleteCount = 0;
    final method = _getModificationMethod(mod[0] as String);

    final path = mod[1];

    if (method == YamlModificationMethod.appendTo ||
        method == YamlModificationMethod.update ||
        method == YamlModificationMethod.prependTo) {
      value = mod[2];
    } else if (method == YamlModificationMethod.insert) {
      index = mod[2] as int;
      value = mod[3];
    } else if (method == YamlModificationMethod.splice) {
      index = mod[2] as int;
      deleteCount = mod[3] as int;

      if (mod[4] is! List) {
        throw ArgumentError('Invalid array ${mod[4]} used in splice');
      }

      value = mod[4];
    }

    return _YamlModification(method, path, index, value, deleteCount);
  }).toList();
}

/// Gets the YAML modification method corresponding to [method]
YamlModificationMethod _getModificationMethod(String method) {
  switch (method) {
    case 'update':
      return YamlModificationMethod.update;
    case 'remove':
      return YamlModificationMethod.remove;
    case 'append':
    case 'appendTo':
      return YamlModificationMethod.appendTo;
    case 'prepend':
    case 'prependTo':
      return YamlModificationMethod.prependTo;
    case 'insert':
    case 'insertIn':
      return YamlModificationMethod.insert;
    case 'splice':
      return YamlModificationMethod.splice;
    default:
      throw Exception('$method not recognized!');
  }
}

/// Class representing an abstract YAML modification to be performed
class _YamlModification {
  final YamlModificationMethod method;
  final List<Object?> path;
  final int index;
  final dynamic value;
  final int deleteCount;

  _YamlModification(
      this.method, this.path, this.index, this.value, this.deleteCount);

  @override
  String toString() =>
      'method: $method, path: $path, index: $index, value: $value, deleteCount: $deleteCount';
}
