// 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 <unistd.h>
#include <zircon/status.h>

#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "lib/ui/input/cpp/formatting.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::Request font_request;
  font_request.family = "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
