/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.copybara.util.console;

import static com.google.copybara.util.console.AnsiColor.BLUE;
import static com.google.copybara.util.console.AnsiColor.GREEN;
import static com.google.copybara.util.console.AnsiColor.RED;
import static com.google.copybara.util.console.AnsiColor.YELLOW;

import com.google.common.base.Preconditions;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

/**
 * A console that prints the the output using fancy ANSI capabilities.
 */
public final class AnsiConsole implements Console {

  private final InputStream input;
  private final PrintStream output;
  private boolean lastWasProgress = false;
  private final Object lock = new Object();

  //blue red yellow blue green red
  public AnsiConsole(InputStream input, PrintStream output) {
    this.input = Preconditions.checkNotNull(input);
    this.output = Preconditions.checkNotNull(output);
  }

  @Override
  public void startupMessage() {
    // Just because we can!
    output.println(BLUE.write("C")
        + RED.write("o")
        + YELLOW.write("p")
        + BLUE.write("y")
        + GREEN.write("b")
        + RED.write("a")
        + BLUE.write("r")
        + RED.write("a")+" source mover"
    );
  }

  @Override
  public void error(String message) {
    synchronized (lock) {
      lastWasProgress = false;
      output.println(RED.write("ERROR: ") + message);
    }
  }

  @Override
  public void warn(String message) {
    synchronized (lock) {
      lastWasProgress = false;
      output.println(YELLOW.write("WARN: ") + message);
    }
  }

  @Override
  public void info(String message) {
    synchronized (lock) {
      lastWasProgress = false;
      output.println(GREEN.write("INFO: ") + message);
    }
  }

  @Override
  public void progress(String progress) {
    synchronized (lock) {
      if (lastWasProgress) {
        output.print(AnsiEscapes.oneLineUp() + AnsiEscapes.deleteLine());
      }
      output.println(GREEN.write("Task: ") + progress);
      lastWasProgress = true;
    }
  }

  @Override
  public boolean promptConfirmation(String message) throws IOException {
    return new ConsolePrompt(input, msg -> {
      synchronized (lock) {
        lastWasProgress = false;
        output.print(YELLOW.write("WARN: ") + msg + " [y/n] ");
      }
    }).promptConfirmation(message);
  }

  @Override
  public String colorize(AnsiColor ansiColor, String message) {
    return ansiColor.write(message);
  }
}

@@ -921,23 +921,104 @@
 ase.
-Preconditions;%0A
+CharMatcher;%0Aimport com.google.common.base.Preconditions;%0Aimport com.google.common.base.Strings;
 %0Aimp
@@ -1231,16 +1231,188 @@
 sole %7B%0A%0A
+  private static final CharMatcher NEWLINE_COUNTER = CharMatcher.is('%5Cn');%0A  private static final String REMOVE_LINE = AnsiEscapes.oneLineUp() + AnsiEscapes.deleteLine();%0A%0A
   privat
@@ -1478,51 +1478,8 @@
 ut;%0A
-  private boolean lastWasProgress = false;%0A
   pr
@@ -1517,16 +1517,56 @@
 bject();
+%0A  %0A  private int lastProgressLines = 0;
 %0A%0A  //bl
@@ -2167,35 +2167,32 @@
 %7B%0A      last
-Was
 Progress
  = false;%0A  
@@ -2175,32 +2175,33 @@
 lastProgress
- = false
+Lines = 0
 ;%0A      outp
@@ -2336,35 +2336,32 @@
 %7B%0A      last
-Was
 Progress
  = false;%0A  
@@ -2344,32 +2344,33 @@
 lastProgress
- = false
+Lines = 0
 ;%0A      outp
@@ -2507,35 +2507,32 @@
 %7B%0A      last
-Was
 Progress
  = false;%0A  
@@ -2515,32 +2515,33 @@
 lastProgress
- = false
+Lines = 0
 ;%0A      outp
@@ -2690,27 +2690,24 @@
 if (last
-Was
 Progress
 ) %7B%0A    
@@ -2694,24 +2694,33 @@
 lastProgress
+Lines %3E 0
 ) %7B%0A        
@@ -2736,57 +2736,53 @@
 int(
-AnsiEscapes.oneLineUp() + AnsiEscapes.delete
+Strings.repeat(REMOVE_LINE, lastProgress
 Line
-(
+s
 ));%0A
@@ -2855,27 +2855,24 @@
     last
-Was
 Progress
  = true;
@@ -2867,15 +2867,53 @@
 ress
- = true
+Lines = 1 + NEWLINE_COUNTER.countIn(progress)
 ;%0A  
@@ -3095,19 +3095,16 @@
 last
-Was
 Progress
  = f
@@ -3103,16 +3103,17 @@
 ress
- = false
+Lines = 0
 ;%0A  

Allow multiline console.progress()