/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.idea.blaze.base.lang.buildfile.formatting;

import com.google.common.collect.Lists;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildToken;
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementTypes;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.FileASTNode;
import com.intellij.lang.folding.FoldingBuilder;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;

import javax.annotation.Nullable;
import java.util.List;

/**
 * Simple code block folding for BUILD files.
 */
public class BuildFileFoldingBuilder implements FoldingBuilder {

  /**
   * Currently only folding top-level nodes.
   */
  @Override
  public FoldingDescriptor[] buildFoldRegions(ASTNode node, Document document) {
    List<FoldingDescriptor> descriptors = Lists.newArrayList();
    if (node instanceof FileASTNode) {
      for (ASTNode child : node.getChildren(null)) {
        addDescriptors(descriptors, child);
      }
    } else if (isTopLevel(node)) {
      addDescriptors(descriptors, node);
    }
    return descriptors.toArray(new FoldingDescriptor[0]);
  }

  /**
   * Only folding top-level statements
   */
  private void addDescriptors(List<FoldingDescriptor> descriptors, ASTNode node) {
    IElementType type = node.getElementType();
    if (type == BuildElementTypes.FUNCTION_STATEMENT) {
      ASTNode colon = node.findChildByType(BuildToken.fromKind(TokenKind.COLON));
      if (colon == null) {
        return;
      }
      ASTNode stmtList = node.findChildByType(BuildElementTypes.STATEMENT_LIST);
      if (stmtList == null) {
        return;
      }
      int start = colon.getStartOffset() + 1;
      int end = endOfList(stmtList);
      descriptors.add(new FoldingDescriptor(node, range(start, end)));

    } else if (type == BuildElementTypes.FUNCALL_EXPRESSION || type == BuildElementTypes.LOAD_STATEMENT) {
      ASTNode listNode = type == BuildElementTypes.FUNCALL_EXPRESSION ? node.findChildByType(BuildElementTypes.ARGUMENT_LIST) : node;
      if (listNode == null) {
        return;
      }
      ASTNode lParen = listNode.findChildByType(BuildToken.fromKind(TokenKind.LPAREN));
      ASTNode rParen = listNode.findChildByType(BuildToken.fromKind(TokenKind.RPAREN));
      if (lParen == null || rParen == null) {
        return;
      }
      int start = lParen.getStartOffset() + 1;
      int end = rParen.getTextRange().getEndOffset() - 1;
      descriptors.add(new FoldingDescriptor(node, range(start, end)));
    }
  }

  private static TextRange range(int start, int end) {
    if (start >= end) {
      return new TextRange(start, start + 1);
    }
    return new TextRange(start, end);
  }

  /**
   * Don't include whitespace and newlines at the end of the function.<br>
   * Could do this in the lexer instead, with additional look-ahead checks.
   */
  private int endOfList(ASTNode stmtList) {
    ASTNode child = stmtList.getLastChildNode();
    while (child != null) {
      IElementType type = child.getElementType();
      if (type != TokenType.WHITE_SPACE
        && type != BuildToken.fromKind(TokenKind.NEWLINE)) {
        return child.getTextRange().getEndOffset();
      }
      child = child.getTreePrev();
    }
    return stmtList.getTextRange().getEndOffset();
  }

  private boolean isTopLevel(ASTNode node) {
    return node.getTreeParent() instanceof FileASTNode;
  }

  @Override
  @Nullable
  public String getPlaceholderText(ASTNode node) {
    PsiElement psi = node.getPsi();
    if (psi instanceof FuncallExpression) {
      FuncallExpression expr = (FuncallExpression) psi;
      String name = expr.getNameArgumentValue();
      if (name != null) {
        return "name = \"" + name + "\"...";
      }
    }
    if (psi instanceof LoadStatement) {
      String fileName = ((LoadStatement) psi).getImportedPath();
      if (fileName != null) {
        return "\"" + fileName + "\"...";
      }
    }
    return "...";
  }

  @Override
  public boolean isCollapsedByDefault(ASTNode node) {
    return false;
  }
}
