/*
 * Copyright (C) 2020 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.
 */

#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_

#include "src/trace_processor/storage/trace_storage.h"

namespace perfetto {
namespace trace_processor {

// Tracks information in the metadata table.
class MetadataTracker {
 public:
  MetadataTracker(TraceStorage* storage);

  // Example usage:
  // SetMetadata(metadata::benchmark_name,
  //             Variadic::String(storage->InternString("foo"));
  // Returns the id of the new entry.
  MetadataId SetMetadata(metadata::KeyId key, Variadic value);

  // Example usage:
  // AppendMetadata(metadata::benchmark_story_tags,
  //                Variadic::String(storage->InternString("bar"));
  // Returns the id of the new entry.
  MetadataId AppendMetadata(metadata::KeyId key, Variadic value);

  // Sets a metadata entry using any interned string as key.
  // Returns the id of the new entry.
  MetadataId SetDynamicMetadata(StringId key, Variadic value);

  // Reads back a set metadata value.
  // Only kSingle types are supported right now.
  SqlValue GetMetadata(metadata::KeyId key);

  // Tracks how many ChromeMetadata bundles have been parsed.
  uint32_t IncrementChromeMetadataBundleCount() {
    return ++chrome_metadata_bundle_count_;
  }

 private:
  static constexpr size_t kNumKeys =
      static_cast<size_t>(metadata::KeyId::kNumKeys);
  static constexpr size_t kNumKeyTypes =
      static_cast<size_t>(metadata::KeyType::kNumKeyTypes);

  void WriteValue(uint32_t row, Variadic value);

  std::array<StringId, kNumKeys> key_ids_;
  std::array<StringId, kNumKeyTypes> key_type_ids_;
  uint32_t chrome_metadata_bundle_count_ = 0;

  TraceStorage* storage_;
};

}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_METADATA_TRACKER_H_
