/*
 * 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 <stddef.h>
#include <stdint.h>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/tracing/core/basic_types.h"
#include "src/profiling/common/unwind_support.h"
#include "src/profiling/memory/shared_ring_buffer.h"
#include "src/profiling/memory/unwinding.h"
#include "src/profiling/memory/unwound_messages.h"

namespace perfetto {
namespace profiling {
namespace {

class NopDelegate : public UnwindingWorker::Delegate {
  void PostAllocRecord(UnwindingWorker*,
                       std::unique_ptr<AllocRecord>) override {}
  void PostFreeRecord(UnwindingWorker*, std::vector<FreeRecord>) override {}
  void PostHeapNameRecord(UnwindingWorker*, HeapNameRecord) override {}
  void PostSocketDisconnected(UnwindingWorker*,
                              DataSourceInstanceID,
                              pid_t,
                              SharedRingBuffer::Stats) override {}
  void PostDrainDone(UnwindingWorker*, DataSourceInstanceID) override {}
};

int FuzzUnwinding(const uint8_t* data, size_t size) {
  SharedRingBuffer::Buffer buf(const_cast<uint8_t*>(data), size, 0u);

  pid_t self_pid = getpid();
  DataSourceInstanceID id = 0;
  UnwindingMetadata metadata(base::OpenFile("/proc/self/maps", O_RDONLY),
                             base::OpenFile("/proc/self/mem", O_RDONLY));

  NopDelegate nop_delegate;
  UnwindingWorker::ClientData client_data{
      id, {}, std::move(metadata), {}, {}, {}, {},
  };

  AllocRecordArena arena;
  UnwindingWorker::HandleBuffer(nullptr, &arena, buf, &client_data, self_pid,
                                &nop_delegate);
  return 0;
}

}  // namespace
}  // namespace profiling
}  // namespace perfetto

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  return perfetto::profiling::FuzzUnwinding(data, size);
}
