/*
 * Copyright (C) 2018 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 "src/tracing/test/mock_producer.h"

#include "perfetto/ext/tracing/core/client_identity.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/ext/tracing/core/tracing_service.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "perfetto/tracing/core/data_source_config.h"
#include "perfetto/tracing/core/data_source_descriptor.h"
#include "protos/perfetto/common/track_event_descriptor.pbzero.h"
#include "src/base/test/test_task_runner.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Property;

namespace perfetto {

namespace {

static DataSourceDescriptor CreateDataSourceDescriptor(
    const std::initializer_list<std::string>& categories,
    uint32_t id) {
  DataSourceDescriptor ds_desc;
  ds_desc.set_name("track_event");
  ds_desc.set_id(id);

  protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
  for (auto c : categories) {
    auto cat = ted->add_available_categories();
    cat->set_name(c);
  }
  ds_desc.set_track_event_descriptor_raw(ted.SerializeAsString());
  return ds_desc;
}

}  // anonymous namespace

MockProducer::MockProducer(base::TestTaskRunner* task_runner)
    : task_runner_(task_runner) {}

MockProducer::~MockProducer() {
  if (!service_endpoint_)
    return;
  static int i = 0;
  auto checkpoint_name = "on_producer_disconnect_" + std::to_string(i++);
  auto on_disconnect = task_runner_->CreateCheckpoint(checkpoint_name);
  EXPECT_CALL(*this, OnDisconnect()).WillOnce(Invoke(on_disconnect));
  service_endpoint_.reset();
  task_runner_->RunUntilCheckpoint(checkpoint_name);
}

void MockProducer::Connect(TracingService* svc,
                           const std::string& producer_name,
                           uid_t uid,
                           pid_t pid,
                           size_t shared_memory_size_hint_bytes,
                           size_t shared_memory_page_size_hint_bytes,
                           std::unique_ptr<SharedMemory> shm,
                           bool in_process) {
  producer_name_ = producer_name;
  service_endpoint_ =
      svc->ConnectProducer(this, ClientIdentity(uid, pid), producer_name,
                           shared_memory_size_hint_bytes,
                           /*in_process=*/in_process,
                           TracingService::ProducerSMBScrapingMode::kDefault,
                           shared_memory_page_size_hint_bytes, std::move(shm));
  auto checkpoint_name = "on_producer_connect_" + producer_name;
  auto on_connect = task_runner_->CreateCheckpoint(checkpoint_name);
  EXPECT_CALL(*this, OnConnect()).WillOnce(Invoke(on_connect));
  task_runner_->RunUntilCheckpoint(checkpoint_name);
}

void MockProducer::RegisterDataSource(const std::string& name,
                                      bool ack_stop,
                                      bool ack_start,
                                      bool handle_incremental_state_clear,
                                      bool no_flush) {
  DataSourceDescriptor ds_desc;
  ds_desc.set_name(name);
  ds_desc.set_will_notify_on_stop(ack_stop);
  ds_desc.set_will_notify_on_start(ack_start);
  ds_desc.set_handles_incremental_state_clear(handle_incremental_state_clear);
  ds_desc.set_no_flush(no_flush);
  service_endpoint_->RegisterDataSource(ds_desc);
}

void MockProducer::UnregisterDataSource(const std::string& name) {
  service_endpoint_->UnregisterDataSource(name);
}

void MockProducer::RegisterTrackEventDataSource(
    const std::initializer_list<std::string>& categories,
    uint32_t id) {
  service_endpoint_->RegisterDataSource(
      CreateDataSourceDescriptor(categories, id));
}

void MockProducer::UpdateTrackEventDataSource(
    const std::initializer_list<std::string>& categories,
    uint32_t id) {
  service_endpoint_->UpdateDataSource(
      CreateDataSourceDescriptor(categories, id));
}

void MockProducer::RegisterTraceWriter(uint32_t writer_id,
                                       uint32_t target_buffer) {
  service_endpoint_->RegisterTraceWriter(writer_id, target_buffer);
}

void MockProducer::UnregisterTraceWriter(uint32_t writer_id) {
  service_endpoint_->UnregisterTraceWriter(writer_id);
}

void MockProducer::WaitForTracingSetup() {
  static int i = 0;
  auto checkpoint_name =
      "on_shmem_initialized_" + producer_name_ + "_" + std::to_string(i++);
  auto on_tracing_enabled = task_runner_->CreateCheckpoint(checkpoint_name);
  EXPECT_CALL(*this, OnTracingSetup()).WillOnce(Invoke(on_tracing_enabled));
  task_runner_->RunUntilCheckpoint(checkpoint_name);
}

void MockProducer::WaitForDataSourceSetup(const std::string& name) {
  static int i = 0;
  auto checkpoint_name = "on_ds_setup_" + name + "_" + std::to_string(i++);
  auto on_ds_start = task_runner_->CreateCheckpoint(checkpoint_name);
  EXPECT_CALL(*this,
              SetupDataSource(_, Property(&DataSourceConfig::name, Eq(name))))
      .WillOnce(Invoke([on_ds_start, this](DataSourceInstanceID ds_id,
                                           const DataSourceConfig& cfg) {
        EXPECT_FALSE(data_source_instances_.count(cfg.name()));
        auto target_buffer = static_cast<BufferID>(cfg.target_buffer());
        auto session_id =
            static_cast<TracingSessionID>(cfg.tracing_session_id());
        data_source_instances_.emplace(
            cfg.name(), EnabledDataSource{ds_id, target_buffer, session_id});
        on_ds_start();
      }));
  task_runner_->RunUntilCheckpoint(checkpoint_name);
}

void MockProducer::WaitForDataSourceStart(const std::string& name) {
  static int i = 0;
  auto checkpoint_name = "on_ds_start_" + name + "_" + std::to_string(i++);
  auto on_ds_start = task_runner_->CreateCheckpoint(checkpoint_name);
  EXPECT_CALL(*this,
              StartDataSource(_, Property(&DataSourceConfig::name, Eq(name))))
      .WillOnce(Invoke([on_ds_start, this](DataSourceInstanceID ds_id,
                                           const DataSourceConfig& cfg) {
        // The data source might have been seen already through
        // WaitForDataSourceSetup().
        if (data_source_instances_.count(cfg.name()) == 0) {
          auto target_buffer = static_cast<BufferID>(cfg.target_buffer());
          auto session_id =
              static_cast<TracingSessionID>(cfg.tracing_session_id());
          data_source_instances_.emplace(
              cfg.name(), EnabledDataSource{ds_id, target_buffer, session_id});
        }
        on_ds_start();
      }));
  task_runner_->RunUntilCheckpoint(checkpoint_name);
}

void MockProducer::WaitForDataSourceStop(const std::string& name) {
  static int i = 0;
  auto checkpoint_name = "on_ds_stop_" + name + "_" + std::to_string(i++);
  auto on_ds_stop = task_runner_->CreateCheckpoint(checkpoint_name);
  ASSERT_EQ(1u, data_source_instances_.count(name));
  DataSourceInstanceID ds_id = data_source_instances_[name].id;
  EXPECT_CALL(*this, StopDataSource(ds_id))
      .WillOnce(InvokeWithoutArgs(on_ds_stop));
  task_runner_->RunUntilCheckpoint(checkpoint_name);
  data_source_instances_.erase(name);
}

std::unique_ptr<TraceWriter> MockProducer::CreateTraceWriter(
    const std::string& data_source_name,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  PERFETTO_DCHECK(data_source_instances_.count(data_source_name));
  BufferID buf_id = data_source_instances_[data_source_name].target_buffer;
  return service_endpoint_->CreateTraceWriter(buf_id, buffer_exhausted_policy);
}

void MockProducer::ExpectFlush(TraceWriter* writer_to_flush,
                               bool reply,
                               FlushFlags expected_flags) {
  std::vector<TraceWriter*> writers;
  if (writer_to_flush)
    writers.push_back(writer_to_flush);
  ExpectFlush(writers, reply, expected_flags);
}

void MockProducer::ExpectFlush(std::vector<TraceWriter*> writers_to_flush,
                               bool reply,
                               FlushFlags expected_flags) {
  auto& expected_call = EXPECT_CALL(*this, Flush(_, _, _, _));
  expected_call.WillOnce(
      Invoke([this, writers_to_flush, reply, expected_flags](
                 FlushRequestID flush_req_id, const DataSourceInstanceID*,
                 size_t, FlushFlags actual_flags) {
        if (expected_flags.flags()) {
          EXPECT_EQ(actual_flags, expected_flags);
        }
        for (auto* writer : writers_to_flush) {
          writer->Flush();
        }
        if (reply) {
          service_endpoint_->NotifyFlushComplete(flush_req_id);
        }
      }));
}

DataSourceInstanceID MockProducer::GetDataSourceInstanceId(
    const std::string& name) {
  auto it = data_source_instances_.find(name);
  return it == data_source_instances_.end() ? 0 : it->second.id;
}

const MockProducer::EnabledDataSource* MockProducer::GetDataSourceInstance(
    const std::string& name) {
  auto it = data_source_instances_.find(name);
  return it == data_source_instances_.end() ? nullptr : &it->second;
}

}  // namespace perfetto
