/*
 * 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.projectview;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.projectview.psi.ProjectViewPsiElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.source.tree.LeafElement;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.google.common.truth.Truth.assertThat;

/**
 * Tests for the project view file parser
 */
public class ProjectViewParserTest extends ProjectViewIntegrationTestCase {

  private final List<String> errors = Lists.newArrayList();

  @Override
  protected void doSetup() {
    errors.clear();
    super.doSetup();
  }

  public void testStandardFile() {
    assertThat(parse(
      "directories:",
      "  java/com/google/work",
      "  java/com/google/other",
      "",
      "targets:",
      "  //java/com/google/work/...:all",
      "  //java/com/google/other/...:all"
    )).isEqualTo(Joiner.on("").join(
      "list_section(list_item, list_item), ",
      "list_section(list_item, list_item)"
    ));
    assertNoErrors();
  }

  public void testIncludeScalarSections() {
    assertThat(parse(
      "import java/com/google/work/.blazeproject",
      "",
      "workspace_type: intellij_plugin",
      "",
      "import_target_output:",
      "  //java/com/google/work:target",
      "",
      "excluded_libraries:",
      "  java/com/google/common/*"
    )).isEqualTo(Joiner.on("").join(
      "scalar_section(scalar_item), ",
      "scalar_section(scalar_item), ",
      "list_section(list_item), ",
      "list_section(list_item)"
    ));
    assertNoErrors();
  }

  public void testUnrecognizedKeyword() {
    parse(
      "impart java/com/google/work/.blazeproject",
      "",
      "workspace_trype: intellij_plugin"
    );

    assertContainsErrors(
      "Unrecognized keyword: impart",
      "Unrecognized keyword: workspace_trype");
  }

  private String parse(String... lines) {
    PsiFile file = createPsiFile(".blazeproject", lines);
    collectErrors(file);
    return treeToString(file);
  }

  private String treeToString(PsiElement psi) {
    StringBuilder builder = new StringBuilder();
    nodeToString(psi, builder);
    return builder.toString();
  }

  private void nodeToString(PsiElement psi, StringBuilder builder) {
    if (psi.getNode() instanceof LeafElement) {
      return;
    }
    PsiElement[] children = Arrays.stream(psi.getChildren())
      .filter(t -> t instanceof ProjectViewPsiElement)
      .toArray(PsiElement[]::new);
    if (psi instanceof ProjectViewPsiElement) {
      builder.append(psi.getNode().getElementType());
      appendChildren(children, builder, true);
    } else {
      appendChildren(children, builder, false);
    }
  }

  private void appendChildren(PsiElement[] childPsis, StringBuilder builder, boolean bracket) {
    if (childPsis.length == 0) {
      return;
    }
    if (bracket) {
      builder.append("(");
    }
    nodeToString(childPsis[0], builder);
    for (int i = 1; i < childPsis.length; i++) {
      builder.append(", ");
      nodeToString(childPsis[i], builder);
    }
    if (bracket) {
      builder.append(")");
    }
  }

  private void assertNoErrors() {
    assertThat(errors).isEmpty();
  }

  private void assertContainsErrors(String... errors) {
    assertThat(this.errors).containsAllIn(Arrays.asList(errors));
  }

  private void collectErrors(PsiElement psi) {
    errors.addAll(PsiUtils.findAllChildrenOfClassRecursive(psi, PsiErrorElement.class)
                    .stream()
                    .map(PsiErrorElement::getErrorDescription)
                    .collect(Collectors.toList()));
  }

}
