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

#include <fcntl.h>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/weak_ptr.h>
#include <base/memory/writable_shared_memory_region.h>
#include <base/posix/eintr_wrapper.h>
#include <base/threading/thread.h>

#include "arc/vm/libvda/decode/test/decode_unittest_common.h"
#include "arc/vm/libvda/libvda_decode.h"

namespace {

// Maximum supported output buffers is 32 as set here:
// https://codesearch.chromium.org/chromium/src/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc?rcl=df1fede89a832a708df47f329e265bb3ff3366e3&l=49
constexpr size_t kMaxNumOutputBuffers = 32;

// Maximum number of planes per output buffer.
// TODO(alexlau): Increase this limit?
constexpr size_t kMaxPlanes = 4;

}  // namespace

class Environment {
 public:
  Environment() {
    logging::SetMinLogLevel(logging::LOGGING_FATAL);  // Disable logging.
  }
  Environment(const Environment&) = delete;
  Environment& operator=(const Environment&) = delete;
};

class ReadEventThread {
 public:
  explicit ReadEventThread(int fd) : fd_(fd), thread_("ReadEventThread") {
    CHECK(thread_.StartWithOptions(
        base::Thread::Options(base::MessagePumpType::IO, 0)));
    thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ReadEventThread::StartWatching,
                                  base::Unretained(this)));
  }
  ReadEventThread(const ReadEventThread&) = delete;
  ReadEventThread& operator=(const ReadEventThread&) = delete;

  ~ReadEventThread() {
    thread_.task_runner()->PostTask(
        FROM_HERE,
        base::BindOnce(&ReadEventThread::StopWatching, base::Unretained(this)));
  }

 private:
  void StartWatching() {
    event_pipe_fd_controller_ = base::FileDescriptorWatcher::WatchReadable(
        fd_, base::BindRepeating(&ReadEventThread::OnEventPipeReadable,
                                 weak_factory_.GetWeakPtr()));
  }

  void StopWatching() { event_pipe_fd_controller_.reset(); }

  void OnEventPipeReadable() {
    // Read the events to make sure the pipe buffer doesn't become
    // completely full.
    // TODO(alexlau): Should these events be parsed and responded to?
    vda_event_t event;
    if (!base::ReadFromFD(fd_, reinterpret_cast<char*>(&event),
                          sizeof(vda_event_t))) {
      LOG(ERROR) << "Failed to read from event pipe.";
      return;
    }

    switch (event.event_type) {
      case PICTURE_READY: {
        const picture_ready_event_data_t& picture_ready =
            event.event_data.picture_ready;
        LOG(INFO) << "Received PICTURE_READY event with"
                  << " picture_buffer_id=" << picture_ready.picture_buffer_id
                  << " bitstream_id=" << picture_ready.bitstream_id
                  << " crop_left=" << picture_ready.crop_left
                  << " crop_top=" << picture_ready.crop_top
                  << " crop_right=" << picture_ready.crop_right
                  << " crop_bottom=" << picture_ready.crop_bottom;
        break;
      }
      case PROVIDE_PICTURE_BUFFERS: {
        const provide_picture_buffers_event_data_t& provide_picture_buffers =
            event.event_data.provide_picture_buffers;
        LOG(INFO) << "Received PROVIDE_PICTURE_BUFFERS event with"
                  << " min_num_buffers="
                  << provide_picture_buffers.min_num_buffers
                  << " width=" << provide_picture_buffers.width
                  << " height=" << provide_picture_buffers.height
                  << " visible_rect_left="
                  << provide_picture_buffers.visible_rect_left
                  << " visible_rect_top="
                  << provide_picture_buffers.visible_rect_top
                  << " visible_rect_right="
                  << provide_picture_buffers.visible_rect_right
                  << " visible_rect_bottom="
                  << provide_picture_buffers.visible_rect_bottom;
        break;
      }
      case NOTIFY_END_OF_BITSTREAM_BUFFER:
        LOG(INFO) << "Received NOTIFY_END_OF_BITSTREAM_BUFFER event with"
                  << " bitstream_id=" << event.event_data.bitstream_id;
        break;
      case NOTIFY_ERROR:
        LOG(INFO) << "Received NOTIFY_ERROR event with result="
                  << event.event_data.result;
        break;
      case RESET_RESPONSE:
        LOG(INFO) << "Received RESET_RESPONSE event with result="
                  << event.event_data.result;
        break;
      case FLUSH_RESPONSE:
        LOG(INFO) << "Received FLUSH_RESPONSE event with result="
                  << event.event_data.result;
        break;
      default:
        LOG(ERROR) << "Received unknown event type " << event.event_type;
        break;
    }
  }

  // Event pipe FD. SessionManager's |impl| retains ownership and will close it
  // when the decode session is stopped.
  int fd_;
  base::Thread thread_;
  std::unique_ptr<base::FileDescriptorWatcher::Controller>
      event_pipe_fd_controller_;

  base::WeakPtrFactory<ReadEventThread> weak_factory_{this};
};

class ScopedSession {
 public:
  ScopedSession()
      : impl_(SetupImpl(GAVDA)),
        session_(SetupSession(impl_, H264PROFILE_MIN)) {}
  ScopedSession(const ScopedSession&) = delete;
  ScopedSession& operator=(const ScopedSession&) = delete;

  ~ScopedSession() { DestroyImpl(); }

  void RecreateImplAndSession() {
    DestroyImpl();
    impl_ = SetupImpl(GAVDA);
    RecreateSession();
  }

  void RecreateSession() {
    DestroySession();
    session_ = SetupSession(impl_, H264PROFILE_MIN);
    event_thread_ = std::make_unique<ReadEventThread>(session_->event_pipe_fd);
  }

  void* impl() { return impl_.get(); }

  void* ctx() { return session_.get()->ctx; }

 private:
  void DestroySession() {
    if (session_) {
      event_thread_.reset();
      session_.reset();
    }
  }

  void DestroyImpl() {
    DestroySession();
    if (impl_) {
      impl_.reset();
    }
  }

  ImplPtr impl_;
  SessionPtr session_;
  std::unique_ptr<ReadEventThread> event_thread_;
};

class DataReader {
 public:
  DataReader(const uint8_t* data, size_t size)
      : data_(data), size_(size), index_(0) {}
  DataReader(const DataReader&) = delete;
  DataReader& operator=(const DataReader&) = delete;

  uint8_t GetUint8() {
    if (index_ >= size_) {
      index_ = 0;
    }
    return data_[index_++];
  }

  uint32_t GetUint32() {
    // We don't care about endianness here, so ordering of the
    // retrieved bytes can be the same for both, as long as the
    // 32 bit integer is populated.
    uint32_t value = 0;
    for (int i = 0; i < 4; ++i) {
      value = (value << 8) | GetUint8();
    }
    return value;
  }

  int32_t GetInt32() {
    uint32_t value = GetUint32();
    int32_t* int_ptr = reinterpret_cast<int32_t*>(&value);
    return *int_ptr;
  }

  size_t GetSize() {
    static_assert(sizeof(size_t) >= 4,
                  "size_t is unexpectedly smaller than 32 bits.");
    return static_cast<size_t>(GetUint32());
  }

 private:
  const uint8_t* data_;
  size_t size_;
  size_t index_;
};

enum class VdaCommand : uint8_t {
  RECREATE_IMPL,
  RECREATE_SESSION,
  GET_CAPABILITIES,
  DECODE,
  SET_OUTPUT_BUFFER_COUNT,
  USE_OUTPUT_BUFFER,
  FLUSH,
  RESET,
  COMMAND_MAX = RESET
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  static Environment env;
  // |session_manager| is a static variable responsible for setting up the VDA
  // session, such that the same connection can be used across different
  // invocations of LLVMFuzzerTestOneInput.
  static ScopedSession session_manager;

  if (!size)
    return 0;

  DataReader reader(data, size);
  VdaCommand command = static_cast<VdaCommand>(
      reader.GetUint8() % (static_cast<uint8_t>(VdaCommand::COMMAND_MAX) + 1));
  LOG(INFO) << "Command: " << static_cast<uint8_t>(command);
  switch (command) {
    case VdaCommand::RECREATE_IMPL:
      session_manager.RecreateImplAndSession();
      break;

    case VdaCommand::RECREATE_SESSION:
      session_manager.RecreateSession();
      break;

    case VdaCommand::GET_CAPABILITIES:
      get_vda_capabilities(session_manager.impl());
      break;

    case VdaCommand::DECODE: {
      const int32_t bitstream_id = reader.GetInt32();
      const bool no_allocate_shm = reader.GetUint8() % 2 == 0;
      uint32_t offset = reader.GetUint32();
      uint32_t bytes_used = reader.GetUint32();
      int fd;
      if (no_allocate_shm) {
        fd = HANDLE_EINTR(open("/dev/urandom", O_RDONLY));
      } else {
        // When allocating, try not to run out of memory.
        offset %= 4096;
        bytes_used %= 4096;

        const size_t data_size = offset + bytes_used;

        base::WritableSharedMemoryRegion shm_region =
            base::WritableSharedMemoryRegion::Create(data_size);
        base::WritableSharedMemoryMapping shm_mapping = shm_region.Map();

        base::ScopedFD random_fd(HANDLE_EINTR(open("/dev/urandom", O_RDONLY)));
        HANDLE_EINTR(read(random_fd.get(), shm_mapping.memory(), data_size));

        base::subtle::PlatformSharedMemoryRegion platform_shm =
            base::WritableSharedMemoryRegion::TakeHandleForSerialization(
                std::move(shm_region));
        base::subtle::PlatformSharedMemoryRegion::ScopedPlatformHandle handle =
            platform_shm.PassPlatformHandle();
        fd = handle.fd.release();
      }
      // Ownership of the FD is passed. We don't hold the fd out of the output
      // buffer as we're not interested in the buffer content when fuzzing.
      vda_decode(session_manager.ctx(), bitstream_id, fd, offset, bytes_used);
      break;
    }

    case VdaCommand::SET_OUTPUT_BUFFER_COUNT: {
      size_t num_output_buffers = reader.GetSize();
      num_output_buffers = num_output_buffers % (kMaxNumOutputBuffers + 1);
      vda_set_output_buffer_count(session_manager.ctx(), num_output_buffers);
      break;
    }

    case VdaCommand::USE_OUTPUT_BUFFER: {
      const int32_t picture_buffer_id = reader.GetInt32();
      const vda_pixel_format_t format = static_cast<vda_pixel_format_t>(
          reader.GetUint32() % (PIXEL_FORMAT_MAX + 1));
      // TODO(alexlau): Consider passing a real dmabuf?
      const int fd = HANDLE_EINTR(open("/dev/urandom", O_RDWR));
      const size_t num_planes = reader.GetSize() % (kMaxPlanes + 1);
      std::vector<video_frame_plane_t> planes(num_planes);
      for (auto& plane : planes) {
        plane.offset = reader.GetInt32();
        plane.stride = reader.GetInt32();
      }
      // Ownership of the FD is passed.
      vda_use_output_buffer(session_manager.ctx(), picture_buffer_id, format,
                            fd, num_planes, planes.data());
      break;
    }
    case VdaCommand::FLUSH: {
      vda_flush(session_manager.ctx());
      break;
    }
    case VdaCommand::RESET: {
      vda_reset(session_manager.ctx());
      break;
    }
    default:
      NOTREACHED();
  }

  return 0;
}
