// Copyright 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 "chrome/browser/diagnostics/diagnostics_writer.h"

#include <stdint.h>

#include <string>

#include "base/command_line.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
#include "ui/base/ui_base_paths.h"

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

namespace diagnostics {

// This is a minimalistic interface to wrap the platform console.
class SimpleConsole {
 public:
  enum Color {
    DEFAULT,
    RED,
    GREEN,
  };

  virtual ~SimpleConsole() {}

  // Init must be called before using any other method. If it returns
  // false there will be no console output.
  virtual bool Init() = 0;

  // Writes a string to the console with the current color.
  virtual bool Write(const base::string16& text) = 0;

  // Called when the program is about to exit.
  virtual void OnQuit() = 0;

  // Sets the foreground text color.
  virtual bool SetColor(Color color) = 0;

  // Create an appropriate SimpleConsole instance.  May return NULL if there is
  // no implementation for the current platform.
  static SimpleConsole* Create();
};

#if defined(OS_WIN)
namespace {

// Wrapper for the windows console operating in high-level IO mode.
class WinConsole : public SimpleConsole {
 public:
  // The ctor allocates a console. This avoids having to ask the user to start
  // chrome from a command prompt.
  WinConsole()
      : std_out_(INVALID_HANDLE_VALUE),
        std_in_(INVALID_HANDLE_VALUE) {
    ::AllocConsole();
  }

  ~WinConsole() override { ::FreeConsole(); }

  bool Init() override { return SetIOHandles(); }

  bool Write(const base::string16& txt) override {
    DWORD sz = txt.size();
    return (TRUE == ::WriteConsoleW(std_out_, txt.c_str(), sz, &sz, NULL));
  }

  // Reads a string from the console. Internally it is limited to 256
  // characters.
  void OnQuit() override {
    // Block here so the user can see the results.
    SetColor(SimpleConsole::DEFAULT);
    Write(L"Press [enter] to continue\n");
    wchar_t buf[256];
    DWORD read = base::size(buf);
    ::ReadConsoleW(std_in_, buf, read, &read, NULL);
  }

  // Sets the foreground and background color.
  bool SetColor(Color color) override {
    uint16_t color_combo = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
                           FOREGROUND_INTENSITY;
    switch (color) {
      case RED:
        color_combo = FOREGROUND_RED | FOREGROUND_INTENSITY;
        break;
      case GREEN:
        color_combo = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
        break;
      case DEFAULT:
        break;
      default:
        NOTREACHED();
    }
    return (TRUE == ::SetConsoleTextAttribute(std_out_, color_combo));
  }

 private:
  bool SetIOHandles() {
    std_out_ = ::GetStdHandle(STD_OUTPUT_HANDLE);
    std_in_ = ::GetStdHandle(STD_INPUT_HANDLE);
    return ((std_out_ != INVALID_HANDLE_VALUE) &&
            (std_in_ != INVALID_HANDLE_VALUE));
  }

  // The input and output handles to the screen. They seem to be
  // implemented as pipes but they have non-documented protocol.
  HANDLE std_out_;
  HANDLE std_in_;

  DISALLOW_COPY_AND_ASSIGN(WinConsole);
};

}  // namespace

SimpleConsole* SimpleConsole::Create() { return new WinConsole(); }

#elif defined(OS_POSIX)
namespace {

class PosixConsole : public SimpleConsole {
 public:
  PosixConsole() : use_color_(false) {}

  bool Init() override {
    // Technically, we should also check the terminal capabilities before using
    // color, but in practice this is unlikely to be an issue.
    use_color_ = isatty(STDOUT_FILENO);
    return true;
  }

  bool Write(const base::string16& text) override {
    // We're assuming that the terminal is using UTF-8 encoding.
    printf("%s", base::UTF16ToUTF8(text).c_str());
    return true;
  }

  void OnQuit() override {
    // The "press enter to continue" prompt isn't very unixy, so only do that on
    // Windows.
  }

  bool SetColor(Color color) override {
    if (!use_color_)
      return false;

    const char* code = "\033[m";
    switch (color) {
      case RED:
        code = "\033[1;31m";
        break;
      case GREEN:
        code = "\033[1;32m";
        break;
      case DEFAULT:
        break;
      default:
        NOTREACHED();
    }
    printf("%s", code);
    return true;
  }

 private:
  bool use_color_;

  DISALLOW_COPY_AND_ASSIGN(PosixConsole);
};

}  // namespace

SimpleConsole* SimpleConsole::Create() { return new PosixConsole(); }

#else  // !defined(OS_WIN) && !defined(OS_POSIX)
SimpleConsole* SimpleConsole::Create() { return NULL; }
#endif

///////////////////////////////////////////////////////////
//  DiagnosticsWriter

DiagnosticsWriter::DiagnosticsWriter(FormatType format)
    : failures_(0), format_(format) {
  // Only create consoles for non-log output.
  if (format_ != LOG) {
    console_.reset(SimpleConsole::Create());
    console_->Init();
  }
}

DiagnosticsWriter::~DiagnosticsWriter() {
  if (console_.get())
    console_->OnQuit();
}

bool DiagnosticsWriter::WriteInfoLine(const std::string& info_text) {
  if (format_ == LOG) {
    LOG(WARNING) << info_text;
    return true;
  } else {
    if (console_.get()) {
      console_->SetColor(SimpleConsole::DEFAULT);
      console_->Write(base::UTF8ToUTF16(info_text + "\n"));
    }
  }
  return true;
}

void DiagnosticsWriter::OnTestFinished(int index, DiagnosticsModel* model) {
  const DiagnosticsModel::TestInfo& test_info = model->GetTest(index);
  bool success = (DiagnosticsModel::TEST_OK == test_info.GetResult());
  WriteResult(success,
              test_info.GetName(),
              test_info.GetTitle(),
              test_info.GetOutcomeCode(),
              test_info.GetAdditionalInfo());
}

void DiagnosticsWriter::OnAllTestsDone(DiagnosticsModel* model) {
  WriteInfoLine(
      base::StringPrintf("Finished %d tests.", model->GetTestRunCount()));
}

void DiagnosticsWriter::OnRecoveryFinished(int index, DiagnosticsModel* model) {
  const DiagnosticsModel::TestInfo& test_info = model->GetTest(index);
  WriteInfoLine("Finished Recovery for: " + test_info.GetTitle());
}

void DiagnosticsWriter::OnAllRecoveryDone(DiagnosticsModel* model) {
  WriteInfoLine("Finished All Recovery operations.");
}

bool DiagnosticsWriter::WriteResult(bool success,
                                    const std::string& id,
                                    const std::string& name,
                                    int outcome_code,
                                    const std::string& extra) {
  std::string result;
  SimpleConsole::Color color;

  if (success) {
    result = "[PASS] ";
    color = SimpleConsole::GREEN;
  } else {
    color = SimpleConsole::RED;
    result = "[FAIL] ";
    failures_++;
  }

  if (format_ != LOG) {
    if (console_.get()) {
      console_->SetColor(color);
      console_->Write(base::ASCIIToUTF16(result));
    }
    if (format_ == MACHINE) {
      return WriteInfoLine(base::StringPrintf(
          "%03d %s (%s)", outcome_code, id.c_str(), extra.c_str()));
    } else {
      return WriteInfoLine(name + "\n       " + extra + "\n");
    }
  } else {
    if (!success) {
      // For log output, we only care about the tests that failed.
      return WriteInfoLine(base::StringPrintf("%s%03d %s (%s)",
                                              result.c_str(),
                                              outcome_code,
                                              id.c_str(),
                                              extra.c_str()));
    }
  }
  return true;
}

}  // namespace diagnostics
