// 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.

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