/*
 * Copyright 2017 The Chromium 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 io.flutter.run.daemon;

import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.SearchScopeProvider;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderImpl;
import com.intellij.execution.filters.UrlFilter;
import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.jetbrains.lang.dart.ide.runner.DartRelativePathsConsoleFilter;
import io.flutter.settings.FlutterSettings;
import io.flutter.utils.StdoutJsonParser;
import org.jetbrains.annotations.NotNull;

/**
 * A console view that filters out JSON messages sent in --machine mode.
 */
public class DaemonConsoleView extends ConsoleViewImpl {
  private static final Logger LOG = Logger.getInstance(DaemonConsoleView.class);

  /**
   * Sets up a launcher to use a DaemonConsoleView.
   */
  public static void install(@NotNull CommandLineState launcher, @NotNull ExecutionEnvironment env, @NotNull VirtualFile workDir) {
    // Create our own console builder.
    // We need to filter input to this console without affecting other consoles,
    // so we cannot use a consoleFilterInputProvider.
    final GlobalSearchScope searchScope = SearchScopeProvider.createSearchScope(env.getProject(), env.getRunProfile());
    final TextConsoleBuilder builder = new TextConsoleBuilderImpl(env.getProject(), searchScope) {
      @NotNull
      @Override
      protected ConsoleView createConsole() {
        return new DaemonConsoleView(env.getProject(), searchScope);
      }
    };

    // Set up basic console filters. (More may be added later.)
    builder.addFilter(new DartRelativePathsConsoleFilter(env.getProject(), workDir.getPath()));
    builder.addFilter(new UrlFilter());
    launcher.setConsoleBuilder(builder);
  }

  private final StdoutJsonParser stdoutParser = new StdoutJsonParser();
  private boolean hasPrintedText;

  public DaemonConsoleView(@NotNull final Project project, @NotNull final GlobalSearchScope searchScope) {
    super(project, searchScope, true, false);
  }

  @Override
  public void print(@NotNull String text, @NotNull ConsoleViewContentType contentType) {
    if (FlutterSettings.getInstance().isVerboseLogging()) {
      super.print(text, contentType);
      return;
    }

    if (text.trim().startsWith("Observatory listening on http")) {
      return;
    }

    stdoutParser.appendOutput(text);

    for (String line : stdoutParser.getAvailableLines()) {
      final String trimmed = line.trim();

      if (trimmed.startsWith("[{") && trimmed.endsWith("}]")) {
        LOG.info(trimmed);
        return;
      }
      else {
        // We're seeing a spurious newline before some launches; this removed any single
        // newline that occur before we've printed text.
        if (!hasPrintedText && text.equals(("\n"))) {
          continue;
        }

        hasPrintedText = true;

        super.print(text, contentType);
      }
    }
  }
}

@@ -2898,41 +2898,297 @@
     
-stdoutParser.appendOutput(text);%0A
+if (contentType != ConsoleViewContentType.NORMAL_OUTPUT) %7B%0A      stdoutParser.flush();%0A      writeAvailableLines();%0A%0A      super.print(text, contentType);%0A    %7D%0A    else %7B%0A      stdoutParser.appendOutput(text);%0A      writeAvailableLines();%0A    %7D%0A  %7D%0A%0A  private void writeAvailableLines() %7B
 %0A   
@@ -3591,20 +3591,20 @@
 Text && 
-text
+line
 .equals(
@@ -3697,33 +3697,58 @@
 r.print(
-text, contentType
+line, ConsoleViewContentType.NORMAL_OUTPUT
 );%0A     

fix an issue with the recently introduced console filtering (#1534)