// 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>[]);
    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: null});

  @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;
  }
}
