// Copyright (c) 2018, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';

/**
 * A computer for [CompilationUnit] folding.
 */
class DartUnitFoldingComputer {
  final LineInfo _lineInfo;
  final CompilationUnit _unit;

  Directive _firstDirective, _lastDirective;
  final List<FoldingRegion> _foldingRegions = [];

  DartUnitFoldingComputer(this._lineInfo, this._unit);

  /**
   * Returns a list of folding regions, not `null`.
   */
  List<FoldingRegion> compute() {
    _unit.accept(new _DartUnitFoldingComputerVisitor(this));

    if (_firstDirective != null &&
        _lastDirective != null &&
        _firstDirective != _lastDirective) {
      _foldingRegions.add(new FoldingRegion(
          FoldingKind.DIRECTIVES,
          _firstDirective.keyword.end,
          _lastDirective.end - _firstDirective.keyword.end));
    }

    return _foldingRegions;
  }
}

/**
 * An AST visitor for [DartUnitFoldingComputer].
 */
class _DartUnitFoldingComputerVisitor extends RecursiveAstVisitor<Object> {
  final DartUnitFoldingComputer _computer;
  _DartUnitFoldingComputerVisitor(this._computer);

  @override
  Object visitBlockFunctionBody(BlockFunctionBody node) {
    final FoldingKind kind = node.parent is ConstructorDeclaration ||
            node.parent is MethodDeclaration
        ? FoldingKind.CLASS_MEMBER
        : FoldingKind.TOP_LEVEL_DECLARATION;
    _addRegion(
        node.block.leftBracket.end, node.block.rightBracket.offset, kind);
    return super.visitBlockFunctionBody(node);
  }

  @override
  Object visitClassDeclaration(ClassDeclaration node) {
    _addRegion(node.leftBracket.end, node.rightBracket.offset,
        FoldingKind.TOP_LEVEL_DECLARATION);
    return super.visitClassDeclaration(node);
  }

  @override
  Object visitAnnotation(Annotation node) {
    if (node.arguments != null &&
        node.arguments.leftParenthesis != null &&
        node.arguments.rightParenthesis != null) {
      _addRegion(
          node.arguments.leftParenthesis.end,
          node.arguments.rightParenthesis.offset,
          FoldingKind.TOP_LEVEL_DECLARATION);
    }
    return super.visitAnnotation(node);
  }

  @override
  Object visitComment(Comment node) {
    final FoldingKind kind = node.isDocumentation
        ? FoldingKind.DOCUMENTATION_COMMENT
        : FoldingKind.COMMENT;
    _addRegion(node.offset, node.end, kind);
    return super.visitComment(node);
  }

  @override
  Object visitExportDirective(ExportDirective node) {
    _recordDirective(node);
    return super.visitExportDirective(node);
  }

  @override
  visitImportDirective(ImportDirective node) {
    _recordDirective(node);
    return super.visitImportDirective(node);
  }

  @override
  Object visitLibraryDirective(LibraryDirective node) {
    _recordDirective(node);
    return super.visitLibraryDirective(node);
  }

  @override
  Object visitPartDirective(PartDirective node) {
    _recordDirective(node);
    return super.visitPartDirective(node);
  }

  @override
  Object visitPartOfDirective(PartOfDirective node) {
    _recordDirective(node);
    return super.visitPartOfDirective(node);
  }

  _addRegion(int startOffset, int endOffset, FoldingKind kind) {
    // TODO(dantup): This class is marked deprecated; find out what to change it to.
    final LineInfo_Location start =
        _computer._lineInfo.getLocation(startOffset);
    final LineInfo_Location end = _computer._lineInfo.getLocation(endOffset);

    if (start.lineNumber != end.lineNumber) {
      _computer._foldingRegions
          .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
    }
  }

  _recordDirective(Directive node) {
    _computer._firstDirective ??= node;
    _computer._lastDirective = node;
  }
}
