// Copyright 2016 The Fuchsia 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 "topaz/app/term/view_controller.h"

#include <fuchsia/fonts/cpp/fidl.h>
#include <lib/async/default.h>
#include <lib/zx/clock.h>
#include <unistd.h>
#include <zircon/status.h>

#include "lib/ui/input/cpp/formatting.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkFontMetrics.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "topaz/app/term/key_util.h"
#include "topaz/app/term/pty_server.h"
#include "topaz/app/term/term_model.h"

namespace term {
namespace {

constexpr zx::duration kBlinkInterval = zx::msec(500);
constexpr char kShell[] = "/boot/bin/sh";

}  // namespace

ViewController::ViewController(scenic::ViewContext view_context,
                               const TermParams& term_params,
                               DisconnectCallback disconnect_handler)
    : SkiaView(std::move(view_context), "Term"),
      disconnect_(std::move(disconnect_handler)),
      model_(TermModel::Size(24, 80), this),
      font_loader_(
          startup_context()
              ->ConnectToEnvironmentService<fuchsia::fonts::Provider>()),
      params_(term_params) {
  SetReleaseHandler([this](zx_status_t status) { disconnect_(this); });

  fuchsia::fonts::TypefaceRequest font_request{};
  font_request.set_query(std::move(fuchsia::fonts::TypefaceQuery{}.set_family(
      fuchsia::fonts::FamilyName{.name = "RobotoMono"})));
  font_loader_.LoadFont(
      std::move(font_request), [this](sk_sp<SkTypeface> typeface) {
        FXL_CHECK(typeface);  // TODO(jpoichet): Fail gracefully.
        regular_typeface_ = std::move(typeface);
        ComputeMetrics();
        StartCommandIfNeeded();
      });
}

void ViewController::ComputeMetrics() {
  if (!regular_typeface_)
    return;

  SkFont fg_font;
  fg_font.setTypeface(regular_typeface_);
  fg_font.setSize(params_.font_size);
  // Figure out appropriate metrics.
  SkFontMetrics fm = {};
  fg_font.getMetrics(&fm);

  ascent_ = static_cast<int>(ceilf(-fm.fAscent));
  line_height_ = ascent_ + static_cast<int>(ceilf(fm.fDescent + fm.fLeading));
  FXL_DCHECK(line_height_ > 0);
  // To figure out the advance width, measure an X. Better hope the font
  // is monospace.
  advance_width_ = static_cast<int>(
      ceilf(fg_font.measureText("X", 1, SkTextEncoding::kUTF8)));
  FXL_DCHECK(advance_width_ > 0);
}

void ViewController::StartCommandIfNeeded() {
  if (!regular_typeface_)
    return;
  if (!has_logical_size())
    return;
  if (pty_.process())
    return;

  std::vector<std::string> argv = params_.command;
  if (argv.empty())
    argv = {kShell};

  zx_status_t status = pty_.Run(
      argv,
      [this](const void* bytes, size_t num_bytes) {
        OnDataReceived(bytes, num_bytes);
      },
      [this] { OnCommandTerminated(); });
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "Error starting command: " << status << " ("
                   << zx_status_get_string(status) << ")";
    disconnect_(this);
  }

  Blink();
  InvalidateScene();
}

void ViewController::Blink() {
  if (focused_) {
    zx::duration delta = zx::clock::get_monotonic() - last_key_;
    if (delta > kBlinkInterval) {
      blink_on_ = !blink_on_;
      InvalidateScene();
    }
    blink_task_.Cancel();
    blink_task_.PostDelayed(async_get_default_dispatcher(), kBlinkInterval);
  }
}

void ViewController::OnSceneInvalidated(
    fuchsia::images::PresentationInfo presentation_info) {
  if (!regular_typeface_)
    return;

  SkCanvas* canvas = AcquireCanvas();
  if (canvas) {
    DrawContent(canvas);
    ReleaseAndSwapCanvas();
  }
}

void ViewController::OnPropertiesChanged(
    fuchsia::ui::gfx::ViewProperties old_properties) {
  ComputeMetrics();
  Resize();
}

void ViewController::Resize() {
  if (!has_logical_size() || !regular_typeface_)
    return;

  uint32_t columns = std::max(logical_size().x / advance_width_, 1.f);
  uint32_t rows = std::max(logical_size().y / line_height_, 1.f);
  TermModel::Size current = model_.GetSize();
  if (current.columns != columns || current.rows != rows) {
    model_.SetSize(TermModel::Size(rows, columns), false);
    pty_.SetWindowSize(columns, rows);
  }
  StartCommandIfNeeded();
  InvalidateScene();
}

void ViewController::DrawContent(SkCanvas* canvas) {
  canvas->clear(SK_ColorBLACK);

  SkPaint bg_paint;
  bg_paint.setStyle(SkPaint::kFill_Style);

  SkFont fg_font;
  fg_font.setTypeface(regular_typeface_);
  fg_font.setSize(params_.font_size);

  TermModel::Size size = model_.GetSize();
  int y = 0;
  for (unsigned i = 0; i < size.rows; i++, y += line_height_) {
    int x = 0;
    for (unsigned j = 0; j < size.columns; j++, x += advance_width_) {
      TermModel::CharacterInfo ch =
          model_.GetCharacterInfoAt(TermModel::Position(i, j));

      // Paint the background.
      bg_paint.setColor(SkColorSetRGB(ch.background_color.red,
                                      ch.background_color.green,
                                      ch.background_color.blue));
      canvas->drawRect(SkRect::MakeXYWH(x, y, advance_width_, line_height_),
                       bg_paint);

      // Paint the foreground.
      if (ch.code_point) {
        if (!(ch.attributes & TermModel::kAttributesBlink) || blink_on_) {
          SkPaint fg_paint;
          fg_paint.setAntiAlias(true);
          // TODO(jpoichet): Use real bold font
          if ((ch.attributes & TermModel::kAttributesBold))
            fg_font.setEmbolden(true);
          // TODO(jpoichet): Account for TermModel::kAttributesUnderline
          // without using the deprecated flag SkPaint::kUnderlineText_Flag
          fg_paint.setColor(SkColorSetRGB(ch.foreground_color.red,
                                          ch.foreground_color.green,
                                          ch.foreground_color.blue));

          canvas->drawSimpleText(&ch.code_point, sizeof(ch.code_point),
                                 SkTextEncoding::kUTF32, x, y + ascent_,
                                 fg_font, fg_paint);
        }
      }
    }
  }

  if (model_.GetCursorVisibility() && blink_on_) {
    // Draw the cursor.
    TermModel::Position cursor_pos = model_.GetCursorPosition();
    // TODO(jpoichet): Vary how we draw the cursor, depending on if we're
    // focused and/or active.
    SkPaint caret_paint;
    caret_paint.setStyle(SkPaint::kFill_Style);
    if (!focused_) {
      caret_paint.setStyle(SkPaint::kStroke_Style);
      caret_paint.setStrokeWidth(2);
    }

    caret_paint.setARGB(64, 255, 255, 255);
    canvas->drawRect(SkRect::MakeXYWH(cursor_pos.column * advance_width_,
                                      cursor_pos.row * line_height_,
                                      advance_width_, line_height_),
                     caret_paint);
  }
}

void ViewController::ScheduleDraw(bool force) {
  if (!model_state_changes_.IsDirty() && !force && !force_next_draw_) {
    force_next_draw_ |= force;
    return;
  }

  force_next_draw_ = false;
  InvalidateScene();
}

void ViewController::OnResponse(const void* buf, size_t size) {
  SendData(buf, size);
}

void ViewController::OnSetKeypadMode(bool application_mode) {
  keypad_application_mode_ = application_mode;
}

void ViewController::OnInputEvent(fuchsia::ui::input::InputEvent event) {
  if (event.is_keyboard()) {
    const fuchsia::ui::input::KeyboardEvent& keyboard = event.keyboard();
    if (keyboard.phase == fuchsia::ui::input::KeyboardEventPhase::PRESSED ||
        keyboard.phase == fuchsia::ui::input::KeyboardEventPhase::REPEAT) {
      if (keyboard.code_point == '+' &&
          keyboard.modifiers & fuchsia::ui::input::kModifierAlt) {
        params_.font_size++;
        ComputeMetrics();
        Resize();
      } else if (keyboard.code_point == '-' &&
                 keyboard.modifiers & fuchsia::ui::input::kModifierAlt) {
        params_.font_size--;
        ComputeMetrics();
        Resize();
      }
      OnKeyPressed(std::move(event));
    }
  } else if (event.is_focus()) {
    const fuchsia::ui::input::FocusEvent& focus = event.focus();
    focused_ = focus.focused;
    blink_on_ = true;
    if (focused_) {
      Blink();
    } else {
      InvalidateScene();
    }
  }
}

void ViewController::OnKeyPressed(fuchsia::ui::input::InputEvent key_event) {
  last_key_ = zx::clock::get_monotonic();
  blink_on_ = true;

  std::string input_sequence =
      GetInputSequenceForKeyPressedEvent(key_event, keypad_application_mode_);
  if (input_sequence.empty())
    return;

  SendData(input_sequence.data(), input_sequence.size());
}

void ViewController::SendData(const void* bytes, size_t num_bytes) {
  pty_.Write(bytes, num_bytes);
}

void ViewController::OnDataReceived(const void* bytes, size_t num_bytes) {
  model_.ProcessInput(bytes, num_bytes, &model_state_changes_);
  ScheduleDraw(false);
}

void ViewController::OnCommandTerminated() { disconnect_(this); }

}  // namespace term
