/*
 * Copyright (C) 2019 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 "perfetto/trace_processor/trace_blob.h"

#include <stdlib.h>
#include <string.h>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <sys/mman.h>
#endif

#include <algorithm>

#include "perfetto/base/compiler.h"
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/scoped_mmap.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/trace_processor/basic_types.h"
#include "perfetto/trace_processor/ref_counted.h"

namespace perfetto {
namespace trace_processor {

// static
TraceBlob TraceBlob::Allocate(size_t size) {
  TraceBlob blob(Ownership::kHeapBuf, new uint8_t[size], size);
  PERFETTO_CHECK(blob.data_);
  return blob;
}

// static
TraceBlob TraceBlob::CopyFrom(const void* src, size_t size) {
  TraceBlob blob = Allocate(size);
  const uint8_t* src_u8 = static_cast<const uint8_t*>(src);
  std::copy(src_u8, src_u8 + size, blob.data_);
  return blob;
}

// static
TraceBlob TraceBlob::TakeOwnership(std::unique_ptr<uint8_t[]> buf,
                                   size_t size) {
  PERFETTO_CHECK(buf);
  return TraceBlob(Ownership::kHeapBuf, buf.release(), size);
}

// static
TraceBlob TraceBlob::FromMmap(base::ScopedMmap mapped) {
  PERFETTO_CHECK(mapped.IsValid());
  TraceBlob blob(Ownership::kNullOrMmaped, static_cast<uint8_t*>(mapped.data()),
                 mapped.length());
  blob.mapping_ = std::make_unique<base::ScopedMmap>(std::move(mapped));
  return blob;
}

// static
TraceBlob TraceBlob::FromMmap(void* data, size_t size) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  PERFETTO_CHECK(data);
  TraceBlob blob(Ownership::kNullOrMmaped, static_cast<uint8_t*>(data), size);
  blob.mapping_ = std::make_unique<base::ScopedMmap>(
      base::ScopedMmap::InheritMmappedRange(data, size));
  return blob;
#else
  base::ignore_result(data);
  base::ignore_result(size);
  PERFETTO_FATAL("mmap not supported");
#endif
}

TraceBlob::TraceBlob(Ownership ownership, uint8_t* data, size_t size)
    : ownership_(ownership), data_(data), size_(size) {}

TraceBlob::~TraceBlob() {
  switch (ownership_) {
    case Ownership::kHeapBuf:
      delete[] data_;
      break;

    case Ownership::kNullOrMmaped:
      if (mapping_) {
        PERFETTO_CHECK(mapping_->reset());
      }
      break;
  }
  data_ = nullptr;
  size_ = 0;
}

TraceBlob::TraceBlob(TraceBlob&& other) noexcept
    : RefCounted(std::move(other)) {
  static_assert(
      sizeof(*this) == base::AlignUp<sizeof(void*)>(
                           sizeof(data_) + sizeof(size_) + sizeof(ownership_) +
                           sizeof(mapping_) + sizeof(RefCounted)),
      "TraceBlob move constructor needs updating");
  data_ = other.data_;
  size_ = other.size_;
  ownership_ = other.ownership_;
  mapping_ = std::move(other.mapping_);
  other.data_ = nullptr;
  other.size_ = 0;
  other.ownership_ = Ownership::kNullOrMmaped;
  other.mapping_ = nullptr;
}

TraceBlob& TraceBlob::operator=(TraceBlob&& other) noexcept {
  if (this == &other)
    return *this;
  this->~TraceBlob();
  new (this) TraceBlob(std::move(other));
  return *this;
}

}  // namespace trace_processor
}  // namespace perfetto
