// 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 'dart:collection';

import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/services/available_declarations.dart';
import 'package:analyzer/src/services/available_declarations.dart' as ad;

class Declaration {
  final int fileIndex;
  final LineInfo lineInfo;
  final String name;
  final DeclarationKind kind;
  final int offset;
  final int line;
  final int column;
  final int codeOffset;
  final int codeLength;
  final String className;
  final String mixinName;
  final String parameters;

  Declaration(
    this.fileIndex,
    this.lineInfo,
    this.name,
    this.kind,
    this.offset,
    this.line,
    this.column,
    this.codeOffset,
    this.codeLength,
    this.className,
    this.mixinName,
    this.parameters,
  );
}

enum DeclarationKind {
  CLASS,
  CLASS_TYPE_ALIAS,
  CONSTRUCTOR,
  ENUM,
  ENUM_CONSTANT,
  FIELD,
  FUNCTION,
  FUNCTION_TYPE_ALIAS,
  GETTER,
  METHOD,
  MIXIN,
  SETTER,
  VARIABLE
}

class WorkspaceSymbols {
  final DeclarationsTracker tracker;

  WorkspaceSymbols(this.tracker);

  List<Declaration> declarations(
      RegExp regExp, int maxResults, LinkedHashSet<String> files,
      {String onlyForFile}) {
    _doTrackerWork();

    var declarations = <Declaration>[];

    var pathToIndex = <String, int>{};

    int getPathIndex(String path) {
      var index = pathToIndex[path];
      if (index == null) {
        index = files.length;
        files.add(path);
        pathToIndex[path] = index;
      }
      return index;
    }

    if (maxResults != null && declarations.length >= maxResults) {
      throw const _MaxNumberOfDeclarationsError();
    }

    void addDeclaration(ad.Declaration declaration) {
      if (maxResults != null && declarations.length >= maxResults) {
        throw const _MaxNumberOfDeclarationsError();
      }

      var path = declaration.locationPath;
      if (onlyForFile != null && path != onlyForFile) {
        return;
      }

      declaration.children.forEach(addDeclaration);

      var name = declaration.name;
      if (name.isEmpty) {
        return;
      }
      if (name.endsWith('=')) {
        name = name.substring(0, name.length - 1);
      }
      if (regExp != null && !regExp.hasMatch(name)) {
        return;
      }

      String className;
      if (declaration.parent?.kind == ad.DeclarationKind.CLASS) {
        className = declaration.parent.name;
      }

      String mixinName;
      if (declaration.parent?.kind == ad.DeclarationKind.MIXIN) {
        mixinName = declaration.parent.name;
      }

      declarations.add(
        new Declaration(
          getPathIndex(path),
          declaration.lineInfo,
          name,
          _getTopKind(declaration.kind),
          declaration.locationOffset,
          declaration.locationStartLine,
          declaration.locationStartColumn,
          declaration.codeOffset,
          declaration.codeLength,
          className,
          mixinName,
          declaration.parameters,
        ),
      );
    }

    var libraries = tracker.allLibraries;
    try {
      for (var library in libraries) {
        library.declarations.forEach(addDeclaration);
      }
    } on _MaxNumberOfDeclarationsError {}

    return declarations;
  }

  void _doTrackerWork() {
    while (tracker.hasWork) {
      tracker.doWork();
    }
  }

  static DeclarationKind _getTopKind(ad.DeclarationKind kind) {
    switch (kind) {
      case ad.DeclarationKind.CLASS:
        return DeclarationKind.CLASS;
      case ad.DeclarationKind.CLASS_TYPE_ALIAS:
        return DeclarationKind.CLASS_TYPE_ALIAS;
      case ad.DeclarationKind.CONSTRUCTOR:
        return DeclarationKind.CONSTRUCTOR;
      case ad.DeclarationKind.ENUM:
        return DeclarationKind.ENUM;
      case ad.DeclarationKind.ENUM_CONSTANT:
        return DeclarationKind.ENUM_CONSTANT;
      case ad.DeclarationKind.FIELD:
        return DeclarationKind.FIELD;
      case ad.DeclarationKind.FUNCTION_TYPE_ALIAS:
        return DeclarationKind.FUNCTION_TYPE_ALIAS;
      case ad.DeclarationKind.METHOD:
        return DeclarationKind.METHOD;
      case ad.DeclarationKind.MIXIN:
        return DeclarationKind.MIXIN;
      case ad.DeclarationKind.FUNCTION:
        return DeclarationKind.FUNCTION;
      case ad.DeclarationKind.GETTER:
        return DeclarationKind.GETTER;
      case ad.DeclarationKind.SETTER:
        return DeclarationKind.SETTER;
      case ad.DeclarationKind.VARIABLE:
        return DeclarationKind.VARIABLE;
      default:
        return null;
    }
  }
}

/// The marker class that is thrown to stop adding declarations.
class _MaxNumberOfDeclarationsError {
  const _MaxNumberOfDeclarationsError();
}
