// Copyright 2018 The Chromium OS 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 "media_perception/output_manager.h"

#include <functional>
#include <dbus/object_proxy.h>

#include "media_perception/frame_perception.pb.h"
#include "media_perception/hotword_detection.pb.h"
#include "media_perception/huddly.pb.h"
#include "media_perception/occupancy_trigger.pb.h"
#include "media_perception/presence_perception.pb.h"
#include "media_perception/proto_mojom_conversion.h"
#include "media_perception/serialized_proto.h"

namespace mri {

namespace {

// To avoid passing a lambda as a base::Closure.
void OnConnectionClosedOrError(const std::string& interface_type) {
  LOG(INFO) << "Got closed connection: " << interface_type;
}

}  // namespace

OutputManager::~OutputManager() {
  if (thread_.IsRunning()) {
    base::WaitableEvent destruction_complete(
        base::WaitableEvent::ResetPolicy::MANUAL,
        base::WaitableEvent::InitialState::NOT_SIGNALED);
    thread_.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&OutputManager::DestructDbus, base::Unretained(this),
                       &destruction_complete));
    destruction_complete.Wait();
  }
}

void OutputManager::DestructDbus(base::WaitableEvent* destruction_complete) {
  dbus_connection_.reset();
  destruction_complete->Signal();
}

OutputManager::OutputManager(
    const std::string& configuration_name,
    std::shared_ptr<Rtanalytics> rtanalytics,
    const PerceptionInterfaces& interfaces,
    chromeos::media_perception::mojom::PerceptionInterfacesPtr* interfaces_ptr)
    : thread_("OutputManager Dbus Thread") {
  // Save the configuration name in case we need to reference it later.
  configuration_name_ = configuration_name;
  rtanalytics_ = rtanalytics;

  for (const PerceptionInterface& interface : interfaces.interface()) {
    // Frame perception interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_FRAME_PERCEPTION) {
      (*interfaces_ptr)->frame_perception_handler_request =
          frame_perception_handler_.BindNewPipeAndPassReceiver();
      frame_perception_handler_.set_disconnect_handler(
          base::Bind(&OnConnectionClosedOrError, "INTERFACE_FRAME_PERCEPTION"));

      // Frame perception outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() ==
            PipelineOutputType::OUTPUT_FRAME_PERCEPTION) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleFramePerception, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Hotword detection interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_HOTWORD_DETECTION) {
      (*interfaces_ptr)->hotword_detection_handler_request =
          hotword_detection_handler_.BindNewPipeAndPassReceiver();
      hotword_detection_handler_.set_disconnect_handler(base::Bind(
          &OnConnectionClosedOrError, "INTERFACE_HOTWORD_DETECTION"));

      // Hotword detection outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() ==
            PipelineOutputType::OUTPUT_HOTWORD_DETECTION) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleHotwordDetection, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Presence perception interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_PRESENCE_PERCEPTION) {
      (*interfaces_ptr)->presence_perception_handler_request =
          presence_perception_handler_.BindNewPipeAndPassReceiver();
      presence_perception_handler_.set_disconnect_handler(base::Bind(
          &OnConnectionClosedOrError, "INTERFACE_PRESENCE_PERCEPTION"));

      // Presence perception outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() ==
            PipelineOutputType::OUTPUT_PRESENCE_PERCEPTION) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandlePresencePerception, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Occupancy trigger interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_OCCUPANCY_TRIGGER) {
      (*interfaces_ptr)->occupancy_trigger_handler_request =
          occupancy_trigger_handler_.BindNewPipeAndPassReceiver();
      occupancy_trigger_handler_.set_disconnect_handler(base::Bind(
          &OnConnectionClosedOrError, "INTERFACE_OCCUPANCY_TRIGGER"));

      // Occpancy trigger outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() ==
            PipelineOutputType::OUTPUT_OCCUPANCY_TRIGGER) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleOccupancyTrigger, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Appearances interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_APPEARANCES) {
      (*interfaces_ptr)->appearances_handler_request =
          appearances_handler_.BindNewPipeAndPassReceiver();
      appearances_handler_.set_disconnect_handler(
          base::Bind(&OnConnectionClosedOrError, "APPEARANCES"));

      // Appearances outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() == PipelineOutputType::OUTPUT_APPEARANCES) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleAppearances, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // One touch Autozoom interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_ONE_TOUCH_AUTOZOOM) {
      (*interfaces_ptr)->one_touch_autozoom_handler_request =
          one_touch_autozoom_handler_.BindNewPipeAndPassReceiver();
      one_touch_autozoom_handler_.set_disconnect_handler(
          base::Bind(&OnConnectionClosedOrError, "ONE_TOUCH_AUTOZOOM"));

      // One touch Autozoom outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() == PipelineOutputType::OUTPUT_SMART_FRAMING) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleSmartFraming, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Software Autozoom interface setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_SOFTWARE_AUTOZOOM) {
      (*interfaces_ptr)->software_autozoom_handler_request =
          software_autozoom_handler_.BindNewPipeAndPassReceiver();
      software_autozoom_handler_.set_disconnect_handler(
          base::Bind(&OnConnectionClosedOrError, "SOFTWARE_AUTOZOOM"));

      // Software Autozoom outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() == PipelineOutputType::OUTPUT_SMART_FRAMING) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleSmartFraming, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
          }
        }
      }
      continue;
    }

    // Falcon Autozoom outputs setup.
    if (interface.interface_type() ==
        PerceptionInterfaceType::INTERFACE_FALCON_AUTOZOOM) {
      // Falcon Autozoom outputs setup.
      for (const PipelineOutput& output : interface.output()) {
        if (output.output_type() ==
            PipelineOutputType::OUTPUT_INDEXED_TRANSITIONS) {
          SerializedSuccessStatus serialized_status =
              rtanalytics->SetPipelineOutputHandler(
                  configuration_name, output.stream_name(),
                  std::bind(&OutputManager::HandleIndexedTransitions, this,
                            std::placeholders::_1));
          SuccessStatus status =
              Serialized<SuccessStatus>(serialized_status).Deserialize();
          if (!status.success()) {
            LOG(ERROR) << "Failed to set output handler for "
                       << configuration_name << " with output "
                       << output.stream_name();
            continue;
          }

          if (!thread_.StartWithOptions(
                  base::Thread::Options(base::MessagePumpType::IO, 0))) {
            LOG(ERROR) << "Failed to create dbus thread.";
            continue;
          }
          dbus_connection_ = std::make_unique<brillo::DBusConnection>();
          thread_.task_runner()->PostTask(
              FROM_HERE, base::Bind(&OutputManager::InitializeDbus,
                                    base::Unretained(this)));
        }
      }
      continue;
    }
  }
}

void OutputManager::InitializeDbus() {
  bus_ = dbus_connection_->Connect();
  if (bus_ == nullptr) {
    LOG(FATAL) << "Unable to connect to Dbus from OutputManager.";
  }
  dbus_proxy_ = bus_->GetObjectProxy(
      "org.chromium.IpPeripheralService",
      dbus::ObjectPath("/org/chromium/IpPeripheralService"));
}

void OutputManager::HandleFramePerception(const std::vector<uint8_t>& bytes) {
  if (!frame_perception_handler_.is_bound()) {
    LOG(WARNING) << "Got frame perception output but handler ptr is not bound.";
    return;
  }

  if (frame_perception_handler_.get() == nullptr) {
    LOG(ERROR) << "Handler ptr is null.";
    return;
  }

  FramePerception frame_perception =
      Serialized<FramePerception>(bytes).Deserialize();
  frame_perception_handler_->OnFramePerception(
      chromeos::media_perception::mojom::ToMojom(frame_perception));
}

void OutputManager::HandleHotwordDetection(const std::vector<uint8_t>& bytes) {
  if (!hotword_detection_handler_.is_bound()) {
    LOG(WARNING)
        << "Got hotword detection output but handler ptr is not bound.";
    return;
  }

  if (hotword_detection_handler_.get() == nullptr) {
    LOG(ERROR) << "Handler ptr is null.";
    return;
  }

  HotwordDetection hotword_detection =
      Serialized<HotwordDetection>(bytes).Deserialize();
  hotword_detection_handler_->OnHotwordDetection(
      chromeos::media_perception::mojom::ToMojom(hotword_detection));
}

void OutputManager::HandlePresencePerception(
    const std::vector<uint8_t>& bytes) {
  if (!presence_perception_handler_.is_bound()) {
    LOG(WARNING)
        << "Got presence perception output but handler ptr is not bound.";
    return;
  }

  if (presence_perception_handler_.get() == nullptr) {
    LOG(ERROR) << "Handler ptr is null.";
    return;
  }

  PresencePerception presence_perception =
      Serialized<PresencePerception>(bytes).Deserialize();
  presence_perception_handler_->OnPresencePerception(
      chromeos::media_perception::mojom::ToMojom(presence_perception));
}

void OutputManager::HandleOccupancyTrigger(const std::vector<uint8_t>& bytes) {
  if (!occupancy_trigger_handler_.is_bound()) {
    LOG(WARNING)
        << "Got occupancy trigger output but handler ptr is not bound.";
    return;
  }

  if (occupancy_trigger_handler_.get() == nullptr) {
    LOG(ERROR) << "Handler ptr is null.";
    return;
  }

  OccupancyTrigger occupancy_trigger =
      Serialized<OccupancyTrigger>(bytes).Deserialize();
  occupancy_trigger_handler_->OnOccupancyTrigger(
      chromeos::media_perception::mojom::ToMojom(occupancy_trigger));
}

void OutputManager::HandleAppearances(const std::vector<uint8_t>& bytes) {
  if (!appearances_handler_.is_bound()) {
    LOG(WARNING) << "Got appearances but handler ptr is not bound.";
    return;
  }

  if (appearances_handler_.get() == nullptr) {
    LOG(ERROR) << "Handler ptr is null.";
    return;
  }

  appearances_handler_->OnAppearances(bytes);
}

void OutputManager::HandleSmartFraming(const std::vector<uint8_t>& bytes) {
  if (one_touch_autozoom_handler_.is_bound() &&
      one_touch_autozoom_handler_.get() != nullptr) {
    one_touch_autozoom_handler_->OnSmartFraming(bytes);
  } else if (software_autozoom_handler_.is_bound() &&
             software_autozoom_handler_.get() != nullptr) {
    software_autozoom_handler_->OnSmartFraming(bytes);
  } else {
    LOG(WARNING) << "Got smart framing but handler ptr is not bound.";
  }
}

void OutputManager::HandleIndexedTransitions(
    const std::vector<uint8_t>& bytes) {
  thread_.task_runner()->PostTask(
      FROM_HERE,
      base::BindOnce(&OutputManager::HandleIndexedTransitionsOnDbusThread,
                     base::Unretained(this), bytes));
}

void OutputManager::HandleIndexedTransitionsOnDbusThread(
    const std::vector<uint8_t>& bytes) {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());
  std::string falcon_ip = rtanalytics_->GetFalconIp(configuration_name_);
  std::size_t found = falcon_ip.find_last_of(".");
  if (found == -1) {
    LOG(ERROR) << "Device id is not an IP address.";
    return;
  }

  falcon_ip = falcon_ip.substr(0, found);
  // Send indexed transitions bytes over D-bus to the IP peripheral service.
  if (bytes.size() == 0) {
    dbus::MethodCall method_call("org.chromium.IpPeripheralService.FalconGrpc",
                                 "ResetPTZTransition");
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(falcon_ip);
    dbus_proxy_->CallMethod(&method_call,
                            dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
                            base::BindOnce([](dbus::Response* response) {}));
  } else {
    dbus::MethodCall method_call("org.chromium.IpPeripheralService.FalconGrpc",
                                 "DoPTZTransition");
    dbus::MessageWriter writer(&method_call);
    writer.AppendString(falcon_ip);
    writer.AppendArrayOfBytes(bytes.data(), bytes.size());
    dbus_proxy_->CallMethod(
        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
        base::BindOnce(&OutputManager::HandleFalconPtzTransitionResponse,
                       weak_ptr_factory_.GetWeakPtr()));
  }
}

void OutputManager::HandleFalconPtzTransitionResponse(
    dbus::Response* response) {
  std::vector<uint8_t> serialized_response;
  if (response == nullptr) {
    LOG(ERROR) << "HandleFalconPtzTransitionResponse ignoring dbus nullptr.";
    huddly::IndexedTransitionsResponse itr;
    itr.set_chosen_starting_index(-1);
    serialized_response =
        Serialized<huddly::IndexedTransitionsResponse>(itr).GetBytes();
  } else {
    dbus::MessageReader reader(response);
    // Return the response to rtanalytics.
    const uint8_t* bytes = nullptr;
    size_t size;
    reader.PopArrayOfBytes(&bytes, &size);
    serialized_response.assign(bytes, bytes + size);
  }
  rtanalytics_->RespondToFalconPtzTransition(configuration_name_,
                                             serialized_response);
}

}  // namespace mri
