// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/tracing/public/mojom/trace_config_mojom_traits.h"

#include <utility>

#include "mojo/public/cpp/base/token_mojom_traits.h"
#include "mojo/public/cpp/base/unguessable_token_mojom_traits.h"
#include "services/tracing/public/mojom/data_source_config_mojom_traits.h"

namespace mojo {

// static
bool StructTraits<tracing::mojom::BufferConfigDataView,
                  perfetto::TraceConfig::BufferConfig>::
    Read(tracing::mojom::BufferConfigDataView data,
         perfetto::TraceConfig::BufferConfig* out) {
  out->set_size_kb(data.size_kb());
  perfetto::TraceConfig::BufferConfig::FillPolicy policy;
  if (data.ReadFillPolicy(&policy)) {
    out->set_fill_policy(policy);
  }

  return true;
}

// static
bool StructTraits<tracing::mojom::DataSourceDataView,
                  perfetto::TraceConfig::DataSource>::
    Read(tracing::mojom::DataSourceDataView data,
         perfetto::TraceConfig::DataSource* out) {
  perfetto::DataSourceConfig config;
  if (!data.ReadConfig(&config)) {
    return false;
  }

  *out->mutable_config() = std::move(config);

  std::vector<std::string> producer_name_filter;
  if (!data.ReadProducerNameFilter(&producer_name_filter)) {
    return false;
  }

  for (auto&& filter : producer_name_filter) {
    *out->add_producer_name_filter() = std::move(filter);
  }

  return true;
}

// static
bool StructTraits<tracing::mojom::PerfettoBuiltinDataSourceDataView,
                  perfetto::TraceConfig::BuiltinDataSource>::
    Read(tracing::mojom::PerfettoBuiltinDataSourceDataView data,
         perfetto::TraceConfig::BuiltinDataSource* out) {
  out->set_disable_clock_snapshotting(data.disable_clock_snapshotting());
  out->set_disable_trace_config(data.disable_trace_config());
  out->set_disable_system_info(data.disable_system_info());
  out->set_disable_service_events(data.disable_service_events());
  out->set_primary_trace_clock(static_cast<perfetto::protos::gen::BuiltinClock>(
      data.primary_trace_clock_id()));
  return true;
}

// static
bool StructTraits<tracing::mojom::IncrementalStateConfigDataView,
                  perfetto::TraceConfig::IncrementalStateConfig>::
    Read(tracing::mojom::IncrementalStateConfigDataView data,
         perfetto::TraceConfig::IncrementalStateConfig* out) {
  out->set_clear_period_ms(data.clear_period_ms());
  return true;
}

// static
bool StructTraits<tracing::mojom::TraceConfigDataView, perfetto::TraceConfig>::
    Read(tracing::mojom::TraceConfigDataView data, perfetto::TraceConfig* out) {
  std::vector<perfetto::TraceConfig::DataSource> data_sources;
  std::vector<perfetto::TraceConfig::BufferConfig> buffers;
  std::optional<base::Token> trace_uuid;
  std::optional<base::UnguessableToken> unique_session_name;
  if (!data.ReadDataSources(&data_sources) || !data.ReadBuffers(&buffers) ||
      !data.ReadPerfettoBuiltinDataSource(
          out->mutable_builtin_data_sources()) ||
      !data.ReadIncrementalStateConfig(
          out->mutable_incremental_state_config()) ||
      !data.ReadTraceUuid(&trace_uuid) ||
      !data.ReadUniqueSessionName(&unique_session_name)) {
    return false;
  }

  for (auto&& data_source : data_sources) {
    *out->add_data_sources() = std::move(data_source);
  }

  for (auto&& buffer : buffers) {
    *out->add_buffers() = std::move(buffer);
  }

  out->set_duration_ms(data.duration_ms());
  out->set_write_into_file(data.write_into_file());

  if (trace_uuid) {
    out->set_trace_uuid_msb(trace_uuid->high());
    out->set_trace_uuid_lsb(trace_uuid->low());
  }
  if (unique_session_name) {
    out->set_unique_session_name(unique_session_name->ToString());
  }
  return true;
}

}  // namespace mojo
