// Copyright (c) 2019, 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 'package:_fe_analyzer_shared/src/testing/id_testing.dart';

/// Utility class for annotated testing representing a set of features.
class Features {
  Map<String, Object> _features = {};
  Set<String> _unsorted = new Set<String>();

  Features();

  /// Creates a [Features] registering each key in [featuresMap] as a features
  /// with the corresponding value(s) in the map. Note: values are expected to
  /// be either a single `String` value or a `List<String>`.
  factory Features.fromMap(Map<String, dynamic> featuresMap) {
    Features features = new Features();
    featuresMap.forEach((key, value) {
      if (value is List) {
        for (dynamic v in value) {
          features.addElement(key, v);
        }
      } else {
        features.add(key, value: value);
      }
    });
    return features;
  }

  /// Mark the feature [key] as existing. If [value] is provided, the feature
  /// [key] is set to have this value.
  void add(String key, {var value: ''}) {
    _features[key] = value.toString();
  }

  /// Add [value] as an element of the list values of feature [key].
  void addElement(String key, [var value]) {
    List<String> list =
        _features.putIfAbsent(key, () => <String>[]) as List<String>;
    if (value != null) {
      list.add(value.toString());
    }
  }

  /// Marks list values of [key] as unsorted. This prevents the [getText]
  /// representation from automatically sorting the values.
  void markAsUnsorted(String key) {
    _unsorted.add(key);
  }

  /// Returns `true` if feature [key] exists.
  bool containsKey(String key) {
    return _features.containsKey(key);
  }

  /// Set the feature [key] to exist with the [value].
  void operator []=(String key, String value) {
    _features[key] = value;
  }

  /// Returns the value set for feature [key].
  Object? operator [](String key) => _features[key];

  /// Removes the value set for feature [key]. Returns the existing value.
  Object? remove(String key) => _features.remove(key);

  /// Returns `true` if this feature set is empty.
  bool get isEmpty => _features.isEmpty;

  /// Returns `true` if this feature set is non-empty.
  bool get isNotEmpty => _features.isNotEmpty;

  /// Call [f] for each feature in this feature set with its corresponding
  /// value.
  void forEach(void Function(String, Object) f) {
    _features.forEach(f);
  }

  /// Returns a string containing all features in a comma-separated list sorted
  /// by feature names.
  String getText([String? indent]) {
    if (indent == null) {
      StringBuffer sb = new StringBuffer();
      bool needsComma = false;
      for (String name in _features.keys.toList()..sort()) {
        dynamic value = _features[name];
        if (value != null) {
          if (needsComma) {
            sb.write(',');
          }
          sb.write(name);
          if (value is List<String>) {
            if (_unsorted.contains(name)) {
              value = '[${value.join(',')}]';
            } else {
              value = '[${(value..sort()).join(',')}]';
            }
          }
          if (value != '') {
            sb.write('=');
            sb.write(value);
          }
          needsComma = true;
        }
      }
      return sb.toString();
    } else {
      StringBuffer sb = new StringBuffer();
      Map<String, dynamic> values = {};
      for (String name in _features.keys.toList()..sort()) {
        dynamic value = _features[name];
        if (value != null) {
          values[name] = value;
        }
      }
      String comma = '';
      if (values.length > 1) {
        comma = '\n$indent ';
      }
      values.forEach((String name, dynamic value) {
        sb.write(comma);
        sb.write(name);
        if (value is List<String>) {
          if (value.length > 1) {
            if (_unsorted.contains(name)) {
              value = '[\n$indent  ${value.join(',\n$indent  ')}]';
            } else {
              value = '[\n$indent  ${(value..sort()).join(',\n$indent  ')}]';
            }
          } else {
            if (_unsorted.contains(name)) {
              value = '[${value.join(',')}]';
            } else {
              value = '[${(value..sort()).join(',')}]';
            }
          }
        }
        if (value != '') {
          sb.write('=');
          sb.write(value);
        }
        comma = ',\n$indent ';
      });
      if (values.length > 1) {
        sb.write('\n$indent');
      }
      return sb.toString();
    }
  }

  @override
  String toString() => 'Features(${getText()})';

  /// Creates a [Features] object by parse the [text] encoding.
  ///
  /// Single features will be parsed as strings and list features (features
  /// encoded in `[...]` will be parsed as lists of strings.
  static Features fromText(String? text) {
    Features features = new Features();
    if (text == null) return features;
    int index = 0;
    while (index < text.length) {
      int eqPos = text.indexOf('=', index);
      int commaPos = text.indexOf(',', index);
      String name;
      bool hasValue = false;
      if (eqPos != -1 && commaPos != -1) {
        if (eqPos < commaPos) {
          name = text.substring(index, eqPos);
          hasValue = true;
          index = eqPos + 1;
        } else {
          name = text.substring(index, commaPos);
          index = commaPos + 1;
        }
      } else if (eqPos != -1) {
        name = text.substring(index, eqPos);
        hasValue = true;
        index = eqPos + 1;
      } else if (commaPos != -1) {
        name = text.substring(index, commaPos);
        index = commaPos + 1;
      } else {
        name = text.substring(index);
        index = text.length;
      }
      if (hasValue) {
        const Map<String, String> delimiters = const {
          '[': ']',
          '{': '}',
          '(': ')',
          '<': '>'
        };
        List<String> endDelimiters = <String>[];
        bool isList = index < text.length && text.startsWith('[', index);
        if (isList) {
          features.addElement(name);
          endDelimiters.add(']');
          index++;
        }
        int valueStart = index;
        while (index < text.length) {
          String char = text.substring(index, index + 1);
          if (endDelimiters.isNotEmpty && endDelimiters.last == char) {
            endDelimiters.removeLast();
            index++;
          } else {
            String? endDelimiter = delimiters[char];
            if (endDelimiter != null) {
              endDelimiters.add(endDelimiter);
              index++;
            } else if (char == ',') {
              if (endDelimiters.isEmpty) {
                break;
              } else if (endDelimiters.length == 1 && isList) {
                String value = text.substring(valueStart, index);
                features.addElement(name, value);
                index++;
                valueStart = index;
              } else {
                index++;
              }
            } else {
              index++;
            }
          }
        }
        if (isList) {
          String value = text.substring(valueStart, index - 1);
          if (value.isNotEmpty) {
            features.addElement(name, value);
          }
        } else {
          String value = text.substring(valueStart, index);
          features.add(name, value: value);
        }
        index++;
      } else {
        features.add(name);
      }
    }
    return features;
  }
}

class FeaturesDataInterpreter implements DataInterpreter<Features> {
  final String? wildcard;

  const FeaturesDataInterpreter({this.wildcard});

  @override
  String? isAsExpected(Features actualFeatures, String? expectedData) {
    if (wildcard != null && expectedData == wildcard) {
      return null;
    } else if (expectedData == '') {
      return actualFeatures.isNotEmpty ? "Expected empty data." : null;
    } else {
      List<String> errorsFound = [];
      Features expectedFeatures = Features.fromText(expectedData);
      Set<String> validatedFeatures = new Set<String>();
      expectedFeatures.forEach((String key, Object expectedValue) {
        bool expectMatch = true;
        if (key.startsWith('!')) {
          key = key.substring(1);
          expectMatch = false;
        }
        validatedFeatures.add(key);
        Object? actualValue = actualFeatures[key];
        if (!expectMatch) {
          if (actualFeatures.containsKey(key)) {
            errorsFound.add('Unexpected data found for $key=$actualValue');
          }
        } else if (!actualFeatures.containsKey(key)) {
          errorsFound.add('No data found for $key');
        } else if (expectedValue == '') {
          if (actualValue != '') {
            errorsFound.add('Non-empty data found for $key');
          }
        } else if (wildcard != null && expectedValue == wildcard) {
          return;
        } else if (expectedValue is List) {
          if (actualValue is List) {
            List actualList = actualValue.toList();
            for (Object expectedObject in expectedValue) {
              String expectedText = '$expectedObject';
              bool matchFound = false;
              if (wildcard != null && expectedText.endsWith(wildcard!)) {
                // Wildcard matcher.
                String prefix =
                    expectedText.substring(0, expectedText.indexOf(wildcard!));
                List matches = [];
                for (Object actualObject in actualList) {
                  if ('$actualObject'.startsWith(prefix)) {
                    matches.add(actualObject);
                    matchFound = true;
                  }
                }
                for (Object match in matches) {
                  actualList.remove(match);
                }
              } else {
                for (Object actualObject in actualList) {
                  if (expectedText == '$actualObject') {
                    actualList.remove(actualObject);
                    matchFound = true;
                    break;
                  }
                }
              }
              if (!matchFound) {
                errorsFound.add("No match found for $key=[$expectedText]");
              }
            }
            if (actualList.isNotEmpty) {
              errorsFound
                  .add("Extra data found $key=[${actualList.join(',')}]");
            }
          } else {
            errorsFound.add("List data expected for $key: "
                "expected '$expectedValue', found '${actualValue}'");
          }
        } else if (expectedValue != actualValue) {
          errorsFound.add("Mismatch for $key: expected '$expectedValue', "
              "found '${actualValue}'");
        }
      });
      actualFeatures.forEach((String key, Object value) {
        if (!validatedFeatures.contains(key)) {
          if (value == '') {
            errorsFound.add("Extra data found '$key'");
          } else {
            errorsFound.add("Extra data found $key=$value");
          }
        }
      });
      return errorsFound.isNotEmpty ? errorsFound.join('\n ') : null;
    }
  }

  @override
  String getText(Features actualData, [String? indentation]) {
    return actualData.getText(indentation);
  }

  @override
  bool isEmpty(Features? actualData) {
    return actualData == null || actualData.isEmpty;
  }
}
