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

package fuchsia.developer.plugin.fidl;

import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.SortableTreeElement;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import fuchsia.developer.plugin.fidl.psi.FidlNamedElement;
import fuchsia.developer.plugin.fidl.psi.FidlNamedElementImpl;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import org.jetbrains.annotations.NotNull;

public class FidlStructureViewElement implements StructureViewTreeElement, SortableTreeElement {
  private NavigatablePsiElement element;

  public FidlStructureViewElement(NavigatablePsiElement element) {
    this.element = element;
  }

  @Override
  public Object getValue() {
    return element;
  }

  @Override
  public void navigate(boolean requestFocus) {
    element.navigate(requestFocus);
  }

  @Override
  public boolean canNavigate() {
    return element.canNavigate();
  }

  @Override
  public boolean canNavigateToSource() {
    return element.canNavigateToSource();
  }

  @NotNull
  @Override
  public String getAlphaSortKey() {
    if (element instanceof FidlNamedElement) {
      FidlNamedElement e = (FidlNamedElement) element;
      return e.getIdentifierToken().getText();
    }
    String name = element.getName();
    return name != null ? name : "";
  }

  @NotNull
  @Override
  public ItemPresentation getPresentation() {
    ItemPresentation presentation = element.getPresentation();
    if (presentation != null) {
      return presentation;
    }
    PresentationData data = new PresentationData();
    data.setPresentableText("here");
    return data;
  }

  @Override
  public TreeElement[] getChildren() {
    // Children are the most proximate descendants that implement FidlNamedElementImpl
    List<TreeElement> foundElements = new ArrayList<>();
    Deque<NavigatablePsiElement> elementsToScan = new ArrayDeque<>();
    List<NavigatablePsiElement> initialElements =
        PsiTreeUtil.getChildrenOfTypeAsList(element, NavigatablePsiElement.class);
    elementsToScan.addAll(initialElements);
    while (!elementsToScan.isEmpty()) {
      NavigatablePsiElement curr = elementsToScan.pop();
      if (curr instanceof FidlNamedElementImpl) {
        foundElements.add(new FidlStructureViewElement(curr));
      } else {
        NavigatablePsiElement[] currChildren =
            PsiTreeUtil.getChildrenOfType(curr, NavigatablePsiElement.class);
        if (currChildren == null) {
          continue;
        }
        Collections.addAll(elementsToScan, currChildren);
      }
    }

    return foundElements.toArray(new TreeElement[foundElements.size()]);
  }
}
