// Copyright 2015 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 "mash/task_viewer/task_viewer.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/bind.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/catalog/public/mojom/catalog.mojom.h"
#include "services/catalog/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/mojom/constants.mojom.h"
#include "services/service_manager/public/mojom/service_manager.mojom.h"
#include "ui/base/models/table_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/controls/table/table_view.h"
#include "ui/views/controls/table/table_view_observer.h"
#include "ui/views/mus/aura_init.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace mash {
namespace task_viewer {
namespace {

using service_manager::mojom::RunningServiceInfoPtr;

class TaskViewerContents
    : public views::WidgetDelegateView,
      public ui::TableModel,
      public views::ButtonListener,
      public service_manager::mojom::ServiceManagerListener {
 public:
  TaskViewerContents(
      TaskViewer* task_viewer,
      service_manager::mojom::ServiceManagerListenerRequest request,
      catalog::mojom::CatalogPtr catalog)
      : task_viewer_(task_viewer),
        binding_(this, std::move(request)),
        catalog_(std::move(catalog)),
        table_view_(nullptr),
        table_view_parent_(nullptr),
        kill_button_(
            views::MdTextButton::Create(this,
                                        base::ASCIIToUTF16("Kill Process"))),
        observer_(nullptr),
        weak_ptr_factory_(this) {
    // We don't want to show an empty UI on startup, so just block until we
    // receive the initial set of applications.
    binding_.WaitForIncomingMethodCall();

    table_view_ = new views::TableView(this, GetColumns(), views::TEXT_ONLY,
                                       false);
    SetBackground(views::CreateStandardPanelBackground());

    table_view_parent_ = table_view_->CreateParentIfNecessary();
    AddChildView(table_view_parent_);

    AddChildView(kill_button_);
  }
  ~TaskViewerContents() override {
    table_view_->SetModel(nullptr);
    task_viewer_->RemoveWindow(GetWidget());
  }

 private:
  struct InstanceInfo {
    InstanceInfo(const service_manager::Identity& identity, base::ProcessId pid)
        : identity(identity), pid(pid) {}
    service_manager::Identity identity;
    uint32_t pid;
    std::string display_name;
  };


  // Overridden from views::WidgetDelegate:
  base::string16 GetWindowTitle() const override {
    // TODO(beng): use resources.
    return base::ASCIIToUTF16("Tasks");
  }
  bool CanResize() const override { return true; }
  bool CanMaximize() const override { return true; }
  bool CanMinimize() const override { return true; }

  gfx::ImageSkia GetWindowAppIcon() override {
    // TODO(jamescook): Create a new .pak file for this app and make a custom
    // icon, perhaps one that looks like the Chrome OS task viewer icon.
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_SETTINGS);
  }

  // Overridden from views::View:
  void Layout() override {
    gfx::Rect bounds = GetLocalBounds();
    bounds.Inset(10, 10);

    gfx::Size ps = kill_button_->GetPreferredSize();
    bounds.set_height(bounds.height() - ps.height() - 10);

    kill_button_->SetBounds(bounds.width() - ps.width(),
                            bounds.bottom() + 10,
                            ps.width(), ps.height());
    table_view_parent_->SetBoundsRect(bounds);
  }

  // Overridden from ui::TableModel:
  int RowCount() override {
    return static_cast<int>(instances_.size());
  }
  base::string16 GetText(int row, int column_id) override {
    switch (column_id) {
      case 0:
        DCHECK(row < static_cast<int>(instances_.size()));
        return base::UTF8ToUTF16(instances_[row]->display_name);
      case 1:
        DCHECK(row < static_cast<int>(instances_.size()));
        return base::UTF8ToUTF16(instances_[row]->identity.name());
      case 2:
        DCHECK(row < static_cast<int>(instances_.size()));
        return base::IntToString16(instances_[row]->pid);
      default:
        NOTREACHED();
        break;
    }
    return base::string16();
  }
  void SetObserver(ui::TableModelObserver* observer) override {
    observer_ = observer;
  }

  // Overridden from views::ButtonListener:
  void ButtonPressed(views::Button* sender, const ui::Event& event) override {
    DCHECK_EQ(sender, kill_button_);
    DCHECK_EQ(table_view_->selection_model().size(), 1UL);
    int row = table_view_->FirstSelectedRow();
    DCHECK(row < static_cast<int>(instances_.size()));
    base::Process process = base::Process::Open(instances_[row]->pid);
    process.Terminate(9, true);
  }

  // Overridden from service_manager::mojom::ServiceManagerListener:
  void OnInit(std::vector<RunningServiceInfoPtr> instances) override {
    // This callback should only be called with an empty model.
    DCHECK(instances_.empty());
    std::vector<std::string> names;
    names.reserve(instances.size());
    for (size_t i = 0; i < instances.size(); ++i) {
      const service_manager::Identity& identity = instances[i]->identity;
      InsertInstance(identity, instances[i]->pid);
      names.push_back(identity.name());
    }
    catalog_->GetEntries(std::move(names),
                         base::Bind(&TaskViewerContents::OnGotCatalogEntries,
                                    weak_ptr_factory_.GetWeakPtr()));
  }
  void OnServiceCreated(RunningServiceInfoPtr instance) override {
    service_manager::Identity identity = instance->identity;
    DCHECK(!ContainsIdentity(identity));
    InsertInstance(identity, instance->pid);
    observer_->OnItemsAdded(static_cast<int>(instances_.size()), 1);
    std::vector<std::string> names;
    names.push_back(identity.name());
    catalog_->GetEntries(std::move(names),
                         base::Bind(&TaskViewerContents::OnGotCatalogEntries,
                                    weak_ptr_factory_.GetWeakPtr()));
  }
  void OnServiceStarted(const service_manager::Identity& identity,
                        uint32_t pid) override {
    for (auto it = instances_.begin(); it != instances_.end(); ++it) {
      if ((*it)->identity == identity) {
        (*it)->pid = pid;
        observer_->OnItemsChanged(
          static_cast<int>(it - instances_.begin()), 1);
        return;
      }
    }
  }
  void OnServiceFailedToStart(
      const service_manager::Identity& identity) override {
  }
  void OnServiceStopped(const service_manager::Identity& identity) override {
    for (auto it = instances_.begin(); it != instances_.end(); ++it) {
      if ((*it)->identity == identity) {
        observer_->OnItemsRemoved(
            static_cast<int>(it - instances_.begin()), 1);
        instances_.erase(it);
        return;
      }
    }
    NOTREACHED();
  }
  void OnServicePIDReceived(const service_manager::Identity& identity,
                            uint32_t pid) override {}

  bool ContainsIdentity(const service_manager::Identity& identity) const {
    for (auto& it : instances_) {
      if (it->identity == identity)
        return true;
    }
    return false;
  }

  void InsertInstance(const service_manager::Identity& identity, uint32_t pid) {
    instances_.push_back(std::make_unique<InstanceInfo>(identity, pid));
  }

  void OnGotCatalogEntries(std::vector<catalog::mojom::EntryPtr> entries) {
    for (auto it = instances_.begin(); it != instances_.end(); ++it) {
      for (auto& entry : entries) {
        if (entry->name == (*it)->identity.name()) {
          (*it)->display_name = entry->display_name;
          observer_->OnItemsChanged(
              static_cast<int>(it - instances_.begin()), 1);
          break;
        }
      }
    }
  }

  static std::vector<ui::TableColumn> GetColumns() {
    std::vector<ui::TableColumn> columns;

    ui::TableColumn name_column;
    name_column.id = 0;
    // TODO(beng): use resources.
    name_column.title = base::ASCIIToUTF16("Name");
    name_column.width = -1;
    name_column.percent = 0.4f;
    name_column.sortable = true;
    columns.push_back(name_column);

    ui::TableColumn url_column;
    url_column.id = 1;
    // TODO(beng): use resources.
    url_column.title = base::ASCIIToUTF16("URL");
    url_column.width = -1;
    url_column.percent = 0.4f;
    url_column.sortable = true;
    columns.push_back(url_column);

    ui::TableColumn pid_column;
    pid_column.id = 2;
    // TODO(beng): use resources.
    pid_column.title  = base::ASCIIToUTF16("PID");
    pid_column.width = 50;
    pid_column.sortable = true;
    columns.push_back(pid_column);

    return columns;
  }

  TaskViewer* task_viewer_;
  mojo::Binding<service_manager::mojom::ServiceManagerListener> binding_;
  catalog::mojom::CatalogPtr catalog_;

  views::TableView* table_view_;
  views::View* table_view_parent_;
  views::MdTextButton* kill_button_;
  ui::TableModelObserver* observer_;

  std::vector<std::unique_ptr<InstanceInfo>> instances_;

  base::WeakPtrFactory<TaskViewerContents> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(TaskViewerContents);
};

}  // namespace

TaskViewer::TaskViewer(service_manager::mojom::ServiceRequest request)
    : service_binding_(this, std::move(request)) {
  registry_.AddInterface<::mash::mojom::Launchable>(
      base::Bind(&TaskViewer::Create, base::Unretained(this)));
}

TaskViewer::~TaskViewer() = default;

void TaskViewer::RemoveWindow(views::Widget* widget) {
  auto it = std::find(windows_.begin(), windows_.end(), widget);
  DCHECK(it != windows_.end());
  windows_.erase(it);
  if (windows_.empty())
    Terminate();
}

void TaskViewer::OnStart() {
  views::AuraInit::InitParams params;
  params.connector = service_binding_.GetConnector();
  params.identity = service_binding_.identity();
  aura_init_ = views::AuraInit::Create(params);
  if (!aura_init_)
    Terminate();
}

void TaskViewer::OnBindInterface(
    const service_manager::BindSourceInfo& source_info,
    const std::string& interface_name,
    mojo::ScopedMessagePipeHandle interface_pipe) {
  registry_.BindInterface(interface_name, std::move(interface_pipe));
}

void TaskViewer::Launch(uint32_t what, mojom::LaunchMode how) {
  bool reuse = how == mojom::LaunchMode::REUSE ||
               how == mojom::LaunchMode::DEFAULT;
  if (reuse && !windows_.empty()) {
    windows_.back()->Activate();
    return;
  }

  service_manager::mojom::ServiceManagerPtr service_manager;
  service_binding_.GetConnector()->BindInterface(
      service_manager::mojom::kServiceName, &service_manager);

  catalog::mojom::CatalogPtr catalog;
  service_binding_.GetConnector()->BindInterface(catalog::mojom::kServiceName,
                                                 &catalog);

  service_manager::mojom::ServiceManagerListenerPtr listener;
  TaskViewerContents* task_viewer = new TaskViewerContents(
      this, mojo::MakeRequest(&listener), std::move(catalog));
  views::Widget* window = views::Widget::CreateWindowWithContextAndBounds(
      task_viewer, nullptr, gfx::Rect(10, 10, 500, 500));
  window->Show();
  windows_.push_back(window);
  service_manager->AddListener(std::move(listener));
}

void TaskViewer::Create(::mash::mojom::LaunchableRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

}  // namespace task_viewer
}  // namespace mash
