// Copyright (c) 2013 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.

#include "gn/standard_out.h"

#include <stddef.h>

#include <mutex>
#include <string_view>
#include <vector>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "gn/switches.h"
#include "util/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#else
#include <stdio.h>
#include <unistd.h>
#endif

namespace {

bool initialized = false;

#if defined(OS_WIN)
HANDLE hstdout;
WORD default_attributes;
#endif
bool is_console = false;

bool is_markdown = false;

// True while output is going into a markdown ```...``` code block.
bool in_body = false;

void EnsureInitialized() {
  if (initialized)
    return;
  initialized = true;

  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
  if (cmdline->HasSwitch(switches::kMarkdown)) {
    // Output help in Markdown's syntax, not color-highlighted.
    is_markdown = true;
  }

  if (cmdline->HasSwitch(switches::kNoColor)) {
    // Force color off.
    is_console = false;
    return;
  }

#if defined(OS_WIN)
  // On Windows, we can't force the color on. If the output handle isn't a
  // console, there's nothing we can do about it.
  hstdout = ::GetStdHandle(STD_OUTPUT_HANDLE);
  CONSOLE_SCREEN_BUFFER_INFO info;
  is_console = !!::GetConsoleScreenBufferInfo(hstdout, &info);
  default_attributes = info.wAttributes;
#else
  if (cmdline->HasSwitch(switches::kColor))
    is_console = true;
  else
    is_console = isatty(fileno(stdout));
#endif
}

#if !defined(OS_WIN)
void WriteToStdOut(const std::string& output) {
  size_t written_bytes = fwrite(output.data(), 1, output.size(), stdout);
  DCHECK_EQ(output.size(), written_bytes);
}
#endif  // !defined(OS_WIN)

void OutputMarkdownDec(TextDecoration dec) {
  // The markdown rendering turns "dim" text to italics and any
  // other colored text to bold.

#if defined(OS_WIN)
  DWORD written = 0;
  if (dec == DECORATION_DIM)
    ::WriteFile(hstdout, "*", 1, &written, nullptr);
  else if (dec != DECORATION_NONE)
    ::WriteFile(hstdout, "**", 2, &written, nullptr);
#else
  if (dec == DECORATION_DIM)
    WriteToStdOut("*");
  else if (dec != DECORATION_NONE)
    WriteToStdOut("**");
#endif
}

#if defined(OS_WIN)

void WriteOutputString(std::string_view output,
                       TextDecoration dec,
                       HtmlEscaping escaping) {
  EnsureInitialized();
  DWORD written = 0;

  if (is_markdown) {
    OutputMarkdownDec(dec);
  } else if (is_console) {
    switch (dec) {
      case DECORATION_NONE:
        break;
      case DECORATION_DIM:
        ::SetConsoleTextAttribute(hstdout, FOREGROUND_INTENSITY);
        break;
      case DECORATION_RED:
        ::SetConsoleTextAttribute(hstdout,
                                  FOREGROUND_RED | FOREGROUND_INTENSITY);
        break;
      case DECORATION_GREEN:
        // Keep green non-bold.
        ::SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
        break;
      case DECORATION_BLUE:
        ::SetConsoleTextAttribute(hstdout,
                                  FOREGROUND_BLUE | FOREGROUND_INTENSITY);
        break;
      case DECORATION_YELLOW:
        ::SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_GREEN);
        break;
      case DECORATION_MAGENTA:
        ::SetConsoleTextAttribute(
            hstdout, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
        break;
    }
  }

  std::string tmpstr = std::string(output);
  if (is_markdown && dec == DECORATION_YELLOW) {
    // https://code.google.com/p/gitiles/issues/detail?id=77
    // Gitiles will replace "--" with an em dash in non-code text.
    // Figuring out all instances of this might be difficult, but we can
    // at least escape the instances where this shows up in a heading.
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, "--", "\\--");
  }
  if (is_markdown && !in_body && escaping == DEFAULT_ESCAPING) {
    // Markdown auto-escapes < and > in code sections (and converts &lt; to
    // &amp;tl; there), but not elsewhere.
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, "<", "&lt;");
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, ">", "&gt;");
  }
  ::WriteFile(hstdout, tmpstr.c_str(), static_cast<DWORD>(tmpstr.size()),
              &written, nullptr);

  if (is_markdown) {
    OutputMarkdownDec(dec);
  } else if (is_console) {
    ::SetConsoleTextAttribute(hstdout, default_attributes);
  }
}

#else

void WriteOutputString(std::string_view output,
                       TextDecoration dec,
                       HtmlEscaping escaping) {
  EnsureInitialized();
  if (is_markdown) {
    OutputMarkdownDec(dec);
  } else if (is_console) {
    switch (dec) {
      case DECORATION_NONE:
        break;
      case DECORATION_DIM:
        WriteToStdOut("\e[2m");
        break;
      case DECORATION_RED:
        WriteToStdOut("\e[31m\e[1m");
        break;
      case DECORATION_GREEN:
        WriteToStdOut("\e[32m");
        break;
      case DECORATION_BLUE:
        WriteToStdOut("\e[34m\e[1m");
        break;
      case DECORATION_YELLOW:
        WriteToStdOut("\e[33m");
        break;
      case DECORATION_MAGENTA:
        WriteToStdOut("\e[35m\e[1m");
        break;
    }
  }

  std::string tmpstr = std::string(output);
  if (is_markdown && dec == DECORATION_YELLOW) {
    // https://code.google.com/p/gitiles/issues/detail?id=77
    // Gitiles will replace "--" with an em dash in non-code text.
    // Figuring out all instances of this might be difficult, but we can
    // at least escape the instances where this shows up in a heading.
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, "--", "\\--");
  }
  if (is_markdown && !in_body && escaping == DEFAULT_ESCAPING) {
    // Markdown auto-escapes < and > in code sections (and converts &lt; to
    // &amp;tl; there), but not elsewhere.
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, "<", "&lt;");
    base::ReplaceSubstringsAfterOffset(&tmpstr, 0, ">", "&gt;");
  }
  WriteToStdOut(tmpstr.data());

  if (is_markdown) {
    OutputMarkdownDec(dec);
  } else if (is_console && dec != DECORATION_NONE) {
    WriteToStdOut("\e[0m");
  }
}

#endif

// Collects buffered log output for quiet mode.
class QuietModeBuffer {
 public:
  void Append(std::string_view output,
              TextDecoration decoration,
              HtmlEscaping escaping) {
    {
      std::lock_guard<std::mutex> lock(lock_);
      if (!is_flushed_) {
        output_buffer_.push_back({std::string(output), decoration, escaping});
        return;
      }
      // Otherwise fall-through to printing to stdout outside the lock.
    }
    WriteOutputString(output, decoration, escaping);
  }

  // Outputs any queued output to the standard out.
  void Flush() {
    // Do everything inside the lock so we guarantee we flush all previous
    // output before writing something else from another thread. Flushing will
    // only happen in error cases so this will not be performance-critical.
    std::lock_guard<std::mutex> lock(lock_);

    if (is_flushed_)
      return;
    is_flushed_ = true;

    for (const BufferedOutput& output : output_buffer_) {
      WriteOutputString(output.output, output.decoration, output.escaping);
    }
    output_buffer_.clear();
  }

 private:
  struct BufferedOutput {
    std::string output;
    TextDecoration decoration;
    HtmlEscaping escaping;
  };

  std::mutex lock_;

  // Set when we're in quiet mode but then flush the output. This means that
  // future output should go directly to the terminal (this solves the problem
  // of safely turning "off" quiet mode when we hit an error because
  // quiet_mode_buffer isn't threadsafe).
  bool is_flushed_ = false;

  std::vector<BufferedOutput> output_buffer_;
};

// Non-null while buffering standard output. Deliberately leaked on shutdown.
QuietModeBuffer* quiet_mode_buffer = nullptr;

}  // namespace

bool IsColorEnabled() {
  EnsureInitialized();
  return is_console;
}

void OutputString(std::string_view output,
                  TextDecoration dec,
                  HtmlEscaping escaping) {
  WriteOutputString(output, dec, escaping);
}

void OutputLogString(std::string_view output,
                     TextDecoration dec,
                     HtmlEscaping escaping) {
  if (quiet_mode_buffer) {
    quiet_mode_buffer->Append(output, dec, escaping);
    return;
  }
  WriteOutputString(output, dec, escaping);
}

void BufferLogOutput() {
  if (quiet_mode_buffer) {
    DCHECK(false);  // Expecting to only be called once.
    return;
  }
  quiet_mode_buffer = new QuietModeBuffer();
}

void FlushBufferedOutput() {
  if (quiet_mode_buffer) {
    quiet_mode_buffer->Flush();
  }
}

void PrintSectionHelp(const std::string& line,
                      const std::string& topic,
                      const std::string& tag) {
  EnsureInitialized();

  if (is_markdown) {
    OutputString("*   [" + line + "](#" + tag + ")\n");
  } else if (topic.size()) {
    OutputString("\n" + line + " (type \"gn help " + topic +
                 "\" for more help):\n");
  } else {
    OutputString("\n" + line + ":\n");
  }
}

void PrintShortHelp(const std::string& line, const std::string& link_tag) {
  EnsureInitialized();

  if (is_markdown) {
    if (link_tag.empty())
      OutputString("    *   " + line + "\n");
    else
      OutputString("    *   [" + line + "](#" + link_tag + ")\n");
    return;
  }

  size_t colon_offset = line.find(':');
  size_t first_normal = 0;
  if (colon_offset != std::string::npos) {
    OutputString("  " + line.substr(0, colon_offset), DECORATION_YELLOW);
    first_normal = colon_offset;
  }

  // See if the colon is followed by a " [" and if so, dim the contents of [ ].
  if (first_normal > 0 && line.size() > first_normal + 2 &&
      line[first_normal + 1] == ' ' && line[first_normal + 2] == '[') {
    size_t begin_bracket = first_normal + 2;
    OutputString(": ");
    first_normal = line.find(']', begin_bracket);
    if (first_normal == std::string::npos)
      first_normal = line.size();
    else
      first_normal++;
    OutputString(line.substr(begin_bracket, first_normal - begin_bracket),
                 DECORATION_DIM);
  }

  OutputString(line.substr(first_normal) + "\n");
}

void PrintLongHelp(const std::string& text, const std::string& tag) {
  EnsureInitialized();

  bool first_header = true;
  in_body = false;
  std::size_t empty_lines = 0;
  for (const std::string& line : base::SplitString(
           text, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) {
    // Check for a heading line.
    if (!line.empty() && line[0] != ' ') {
      // New paragraph, just skip any trailing empty lines.
      empty_lines = 0;

      if (is_markdown) {
        // GN's block-level formatting is converted to markdown as follows:
        // * The first heading is treated as an H3.
        // * Subsequent heading are treated as H4s.
        // * Any other text is wrapped in a code block and displayed as-is.
        //
        // Span-level formatting (the decorations) is converted inside
        // OutputString().
        if (in_body) {
          OutputString("```\n\n", DECORATION_NONE);
          in_body = false;
        }

        if (first_header && !tag.empty()) {
          OutputString("### <a name=\"" + tag + "\"></a>", DECORATION_NONE,
                       NO_ESCAPING);
        } else {
          OutputString("#### ", DECORATION_NONE);
        }
      }

      // Highlight up to the colon (if any).
      size_t chars_to_highlight = line.find(':');
      if (chars_to_highlight == std::string::npos)
        chars_to_highlight = line.size();

      OutputString(line.substr(0, chars_to_highlight), DECORATION_YELLOW);
      OutputString(line.substr(chars_to_highlight));
      if (first_header) {
        if (is_markdown) {
          OutputString("&nbsp;[Back to Top](#gn-reference)", DECORATION_NONE);
        }
        first_header = false;
      }
      OutputString("\n");
      continue;
    } else if (is_markdown && !line.empty() && !in_body) {
      OutputString("```\n", DECORATION_NONE);
      in_body = true;
    }

    // We buffer empty lines, so we can skip them if needed
    // (i.e. new paragraph body, end of final paragraph body).
    if (in_body && is_markdown) {
      if (!line.empty() && empty_lines != 0) {
        OutputString(std::string(empty_lines, '\n'));
        empty_lines = 0;
      } else if (line.empty()) {
        ++empty_lines;
        continue;
      }
    }

    // Check for a comment.
    TextDecoration dec = DECORATION_NONE;
    for (const auto& elem : line) {
      if (elem == '#' && !is_markdown) {
        // Got a comment, draw dimmed.
        dec = DECORATION_DIM;
        break;
      } else if (elem != ' ') {
        break;
      }
    }

    OutputString(line + "\n", dec);
  }

  if (is_markdown && in_body)
    OutputString("```\n");
}
