// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// TODO(ahe): Originally copied from sdk/pkg/compiler/lib/src/colors.dart,
// merge these two packages.
library colors;

import 'dart:convert' show jsonEncode;

import 'dart:io' show Platform, Process, ProcessResult, stderr, stdout;

/// ANSI/xterm termcap for setting default colors. Output from Unix
/// command-line program `tput op`.
const String DEFAULT_COLOR = "\x1b[39;49m";

/// ANSI/xterm termcap for setting black text color. Output from Unix
/// command-line program `tput setaf 0`.
const String BLACK_COLOR = "\x1b[30m";

/// ANSI/xterm termcap for setting red text color. Output from Unix
/// command-line program `tput setaf 1`.
const String RED_COLOR = "\x1b[31m";

/// ANSI/xterm termcap for setting green text color. Output from Unix
/// command-line program `tput setaf 2`.
const String GREEN_COLOR = "\x1b[32m";

/// ANSI/xterm termcap for setting yellow text color. Output from Unix
/// command-line program `tput setaf 3`.
const String YELLOW_COLOR = "\x1b[33m";

/// ANSI/xterm termcap for setting blue text color. Output from Unix
/// command-line program `tput setaf 4`.
const String BLUE_COLOR = "\x1b[34m";

/// ANSI/xterm termcap for setting magenta text color. Output from Unix
/// command-line program `tput setaf 5`.
const String MAGENTA_COLOR = "\x1b[35m";

/// ANSI/xterm termcap for setting cyan text color. Output from Unix
/// command-line program `tput setaf 6`.
const String CYAN_COLOR = "\x1b[36m";

/// ANSI/xterm termcap for setting white text color. Output from Unix
/// command-line program `tput setaf 7`.
const String WHITE_COLOR = "\x1b[37m";

/// All the above codes. This is used to compare the above codes to the
/// terminal's. Printing this string should have the same effect as just
/// printing [DEFAULT_COLOR].
const String ALL_CODES = BLACK_COLOR +
    RED_COLOR +
    GREEN_COLOR +
    YELLOW_COLOR +
    BLUE_COLOR +
    MAGENTA_COLOR +
    CYAN_COLOR +
    WHITE_COLOR +
    DEFAULT_COLOR;

const String TERMINAL_CAPABILITIES = """
colors
setaf 0
setaf 1
setaf 2
setaf 3
setaf 4
setaf 5
setaf 6
setaf 7
op
""";

/// Boolean value caching whether or not we should display ANSI colors.
///
/// If `null`, we haven't decided whether we should display ANSI colors or not.
bool _enableColors;

/// Finds out whether we are displaying ANSI colors.
///
/// The first time this getter is invoked (either by a client or by an attempt
/// to use a color), it decides whether colors should be used based on the
/// logic in [_computeEnableColors] (unless a value has previously been set).
bool get enableColors => _enableColors ??= _computeEnableColors();

/// Allows the client to override the decision of whether to disable ANSI
/// colors.
void set enableColors(bool value) {
  assert(value != null);
  _enableColors = value;
}

String wrap(String string, String color) {
  return enableColors ? "${color}$string${DEFAULT_COLOR}" : string;
}

String black(String string) => wrap(string, BLACK_COLOR);
String red(String string) => wrap(string, RED_COLOR);
String green(String string) => wrap(string, GREEN_COLOR);
String yellow(String string) => wrap(string, YELLOW_COLOR);
String blue(String string) => wrap(string, BLUE_COLOR);
String magenta(String string) => wrap(string, MAGENTA_COLOR);
String cyan(String string) => wrap(string, CYAN_COLOR);
String white(String string) => wrap(string, WHITE_COLOR);

/// Returns whether [sink] supports ANSI escapes or `null` if it could not be
/// determined.
bool _supportsAnsiEscapes(sink) {
  try {
    // ignore: undefined_getter
    return sink.supportsAnsiEscapes;
  } on NoSuchMethodError {
    // Ignored: We're running on an older version of the Dart VM which doesn't
    // implement `supportsAnsiEscapes`.
    return null;
  }
}

/// Callback used by [_computeEnableColors] to report why it has or hasn't
/// chosen to use ANSI colors.
void Function(String) printEnableColorsReason = (_) {};

/// True if we should enable colors in output.
///
/// We enable colors when both `stdout` and `stderr` support ANSI escapes.
///
/// On non-Windows platforms, this functions checks the terminal capabilities,
/// on Windows we only enable colors if the VM getters are present and returned
/// `true`.
///
/// Note: do not call this method directly, as it is expensive to
/// compute. Instead, use [CompilerContext.enableColors].
bool _computeEnableColors() {
  bool stderrSupportsColors = _supportsAnsiEscapes(stdout);
  bool stdoutSupportsColors = _supportsAnsiEscapes(stderr);

  if (stdoutSupportsColors == false) {
    printEnableColorsReason(
        "Not enabling colors, stdout does not support ANSI colors.");
    return false;
  }
  if (stderrSupportsColors == false) {
    printEnableColorsReason(
        "Not enabling colors, stderr does not support ANSI colors.");
    return false;
  }

  if (Platform.isWindows) {
    if (stderrSupportsColors != true || stdoutSupportsColors != true) {
      // In this case, either [stdout] or [stderr] did not support the
      // property `supportsAnsiEscapes`. Since we do not have another way
      // to determine support for colors, we disable them.
      printEnableColorsReason("Not enabling colors as ANSI is not supported.");
      return false;
    }
    printEnableColorsReason("Enabling colors as OS is Windows.");
    return true;
  }

  // We have to check if the terminal actually supports colors. Currently,
  // to avoid linking the Dart VM with ncurses, ANSI escape support is reduced
  // to `Platform.environment['TERM'].contains("xterm")`.

  // The `-S` option of `tput` allows us to query multiple capabilities at
  // once.
  ProcessResult result = Process.runSync(
      "/bin/sh", ["-c", "printf '%s' '$TERMINAL_CAPABILITIES' | tput -S"]);

  if (result.exitCode != 0) {
    printEnableColorsReason("Not enabling colors, running tput failed.");
    return false;
  }

  List<String> lines = result.stdout.split("\n");

  if (lines.length != 2) {
    printEnableColorsReason("Not enabling colors, unexpected output from tput: "
        "${jsonEncode(result.stdout)}.");
    return false;
  }

  String numberOfColors = lines[0];
  if ((int.tryParse(numberOfColors) ?? -1) < 8) {
    printEnableColorsReason(
        "Not enabling colors, less than 8 colors supported: "
        "${jsonEncode(numberOfColors)}.");
    return false;
  }

  String allCodes = lines[1].trim();
  if (ALL_CODES != allCodes) {
    printEnableColorsReason("Not enabling colors, color codes don't match: "
        "${jsonEncode(ALL_CODES)} != ${jsonEncode(allCodes)}.");
    return false;
  }

  printEnableColorsReason("Enabling colors.");
  return true;
}
