//
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "trunks/trunks_binder_service.h"

#include <sysexits.h>

#include <base/bind.h>
#include <binderwrapper/binder_wrapper.h>

#include "trunks/binder_interface.h"
#include "trunks/command_transceiver.h"
#include "trunks/error_codes.h"
#include "interface.pb.h"

namespace {

// If |command| is a valid command protobuf, provides the |command_data| and
// returns true. Otherwise, returns false.
bool ParseCommandProto(const std::vector<uint8_t>& command,
                       std::string* command_data) {
  trunks::SendCommandRequest request_proto;
  if (!request_proto.ParseFromArray(command.data(), command.size()) ||
      !request_proto.has_command() || request_proto.command().empty()) {
    return false;
  }
  *command_data = request_proto.command();
  return true;
}

void CreateResponseProto(const std::string& data,
                         std::vector<uint8_t>* response) {
  trunks::SendCommandResponse response_proto;
  response_proto.set_response(data);
  response->resize(response_proto.ByteSize());
  CHECK(response_proto.SerializeToArray(response->data(), response->size()))
      << "TrunksBinderService: Failed to serialize protobuf.";
}

}  // namespace

namespace trunks {

int TrunksBinderService::OnInit() {
  android::BinderWrapper::Create();
  if (!watcher_.Init()) {
    LOG(ERROR) << "TrunksBinderService: BinderWatcher::Init failed.";
    return EX_UNAVAILABLE;
  }
  binder_ = new BinderServiceInternal(this);
  if (!android::BinderWrapper::Get()->RegisterService(
          kTrunksServiceName, android::IInterface::asBinder(binder_))) {
    LOG(ERROR) << "TrunksBinderService: RegisterService failed.";
    return EX_UNAVAILABLE;
  }
  LOG(INFO) << "Trunks: Binder service registered.";
  return brillo::Daemon::OnInit();
}

TrunksBinderService::BinderServiceInternal::BinderServiceInternal(
    TrunksBinderService* service)
    : service_(service) {}

android::binder::Status TrunksBinderService::BinderServiceInternal::SendCommand(
    const std::vector<uint8_t>& command,
    const android::sp<android::trunks::ITrunksClient>& client) {
  auto callback =
      base::Bind(&TrunksBinderService::BinderServiceInternal::OnResponse,
                 GetWeakPtr(), client);
  std::string command_data;
  if (!ParseCommandProto(command, &command_data)) {
    LOG(ERROR) << "TrunksBinderService: Bad command data.";
    callback.Run(CreateErrorResponse(SAPI_RC_BAD_PARAMETER));
    return android::binder::Status::ok();
  }
  service_->transceiver_->SendCommand(command_data, callback);
  return android::binder::Status::ok();
}

void TrunksBinderService::BinderServiceInternal::OnResponse(
    const android::sp<android::trunks::ITrunksClient>& client,
    const std::string& response) {
  std::vector<uint8_t> binder_response;
  CreateResponseProto(response, &binder_response);
  android::binder::Status status = client->OnCommandResponse(binder_response);
  if (!status.isOk()) {
    LOG(ERROR) << "TrunksBinderService: Failed to send response to client: "
               << status.toString8();
  }
}

android::binder::Status
TrunksBinderService::BinderServiceInternal::SendCommandAndWait(
    const std::vector<uint8_t>& command,
    std::vector<uint8_t>* response) {
  std::string command_data;
  if (!ParseCommandProto(command, &command_data)) {
    LOG(ERROR) << "TrunksBinderService: Bad command data.";
    CreateResponseProto(CreateErrorResponse(SAPI_RC_BAD_PARAMETER), response);
    return android::binder::Status::ok();
  }
  CreateResponseProto(service_->transceiver_->SendCommandAndWait(command_data),
                      response);
  return android::binder::Status::ok();
}

}  // namespace trunks
