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

// TODO(https://fxbug.dev/84961): Fix null safety and remove this language version.
// @dart=2.9

class BasicGnParser {
  List<String> imports;
  Map<String, dynamic> assignedVariables;
  List<String> parseErrors;

  BasicGnParser(List gnJson) {
    imports = [];
    assignedVariables = {};
    parseErrors = [];
    _parse(gnJson);
  }

  static String parseIdentifier(Map el) {
    if (el['type'] != 'IDENTIFIER') {
      throw UnsupportedError('Element must be of type IDENTIFIER: $el');
    }
    return el['value'];
  }

  static String parseLiteral(Map el) {
    if (el['type'] != 'LITERAL') {
      throw UnsupportedError('Element must be of type LITERAL: $el');
    }
    var value = el['value'];
    // remove leading and trailing quotes, faster than regex:
    int start = 0, end = value.length;
    if (end > 0 && (value[start] == '\'' || value[start] == '"')) {
      start++;
    }
    if ((end - start) > 0 &&
        (value[end - 1] == '\'' || value[end - 1] == '"')) {
      end--;
    }
    return value.substring(start, end);
  }

  static List<String> parseListOfLiterals(Map listEl) {
    if (listEl['type'] != 'LIST') {
      throw UnsupportedError('Element must be of type LIST: $listEl');
    }
    List<String> result = [];
    for (var el in listEl['child']) {
      result.add(parseLiteral(el));
    }
    return result;
  }

  static dynamic parseLiterals(Map el) {
    String type = el['type'];
    if (type != 'LITERAL' && type != 'LIST') {
      throw UnsupportedError('Element must be of type LITERAL or LIST: $el');
    }
    if (type == 'LITERAL') {
      return parseLiteral(el);
    } else {
      return parseListOfLiterals(el);
    }
  }

  void _parseAssigment(Map el) {
    if (el['type'] != 'BINARY') {
      throw UnsupportedError('Element must be of type BINARY: $el');
    }
    String id = parseIdentifier(el['child'][0]);
    dynamic value = parseLiterals(el['child'][1]);

    bool append = el['value'] == '+=';
    if (append) {
      dynamic previous = assignedVariables[id] ?? [];
      if (previous is! List) {
        previous = [previous];
      }
      if (value is List) {
        previous.addAll(List<String>.from(value));
      } else {
        previous.add(value);
      }
      value = previous;
    }
    assignedVariables[id] = value;
  }

  void _parseFunction(Map el) {
    if (el['type'] != 'FUNCTION') {
      throw UnsupportedError('Element must be of type FUNCTION: $el');
    }
    if (el['value'] != 'import') {
      // silently ignore functions that are not import
      return;
    }
    dynamic value = parseLiterals(el['child'][0]);
    if (value is List<String>) {
      imports.addAll(value);
    } else {
      imports.add(value);
    }
  }

  void _parse(List gnJson) {
    for (Map<String, dynamic> el in gnJson) {
      try {
        switch (el['type']) {
          case 'BINARY':
            _parseAssigment(el);
            break;
          case 'FUNCTION':
            _parseFunction(el);
            break;
          default: // ignore
        }
        // ignore: avoid_catching_errors
      } on UnsupportedError catch (ex) {
        parseErrors.add(ex.message);
      }
    }
  }
}
