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

#ifndef FLUTTER_FML_MAPPING_H_
#define FLUTTER_FML_MAPPING_H_

#include <initializer_list>
#include <memory>
#include <string>
#include <vector>

#include "flutter/fml/build_config.h"
#include "flutter/fml/file.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/unique_fd.h"

namespace fml {

class Mapping {
 public:
  Mapping();

  virtual ~Mapping();

  virtual size_t GetSize() const = 0;

  virtual const uint8_t* GetMapping() const = 0;

  // Whether calling madvise(DONTNEED) on the mapping is non-destructive.
  // Generally true for file-mapped memory and false for anonymous memory.
  virtual bool IsDontNeedSafe() const = 0;

 private:
  FML_DISALLOW_COPY_AND_ASSIGN(Mapping);
};

class FileMapping final : public Mapping {
 public:
  enum class Protection {
    kRead,
    kWrite,
    kExecute,
  };

  explicit FileMapping(const fml::UniqueFD& fd,
                       std::initializer_list<Protection> protection = {
                           Protection::kRead});

  ~FileMapping() override;

  static std::unique_ptr<FileMapping> CreateReadOnly(const std::string& path);

  static std::unique_ptr<FileMapping> CreateReadOnly(
      const fml::UniqueFD& base_fd,
      const std::string& sub_path = "");

  static std::unique_ptr<FileMapping> CreateReadExecute(
      const std::string& path);

  static std::unique_ptr<FileMapping> CreateReadExecute(
      const fml::UniqueFD& base_fd,
      const std::string& sub_path = "");

  // |Mapping|
  size_t GetSize() const override;

  // |Mapping|
  const uint8_t* GetMapping() const override;

  // |Mapping|
  bool IsDontNeedSafe() const override;

  uint8_t* GetMutableMapping();

  bool IsValid() const;

 private:
  bool valid_ = false;
  size_t size_ = 0;
  uint8_t* mapping_ = nullptr;
  uint8_t* mutable_mapping_ = nullptr;

#if FML_OS_WIN
  fml::UniqueFD mapping_handle_;
#endif

  FML_DISALLOW_COPY_AND_ASSIGN(FileMapping);
};

class DataMapping final : public Mapping {
 public:
  explicit DataMapping(std::vector<uint8_t> data);

  explicit DataMapping(const std::string& string);

  ~DataMapping() override;

  // |Mapping|
  size_t GetSize() const override;

  // |Mapping|
  const uint8_t* GetMapping() const override;

  // |Mapping|
  bool IsDontNeedSafe() const override;

 private:
  std::vector<uint8_t> data_;

  FML_DISALLOW_COPY_AND_ASSIGN(DataMapping);
};

class NonOwnedMapping final : public Mapping {
 public:
  using ReleaseProc = std::function<void(const uint8_t* data, size_t size)>;
  NonOwnedMapping(const uint8_t* data,
                  size_t size,
                  const ReleaseProc& release_proc = nullptr,
                  bool dontneed_safe = false);

  ~NonOwnedMapping() override;

  // |Mapping|
  size_t GetSize() const override;

  // |Mapping|
  const uint8_t* GetMapping() const override;

  // |Mapping|
  bool IsDontNeedSafe() const override;

 private:
  const uint8_t* const data_;
  const size_t size_;
  const ReleaseProc release_proc_;
  const bool dontneed_safe_;

  FML_DISALLOW_COPY_AND_ASSIGN(NonOwnedMapping);
};

/// A Mapping like NonOwnedMapping, but uses Free as its release proc.
class MallocMapping final : public Mapping {
 public:
  MallocMapping();

  /// Creates a MallocMapping for a region of memory (without copying it).
  /// The function will `abort()` if the malloc fails.
  /// @param data The starting address of the mapping.
  /// @param size The size of the mapping in bytes.
  MallocMapping(uint8_t* data, size_t size);

  MallocMapping(fml::MallocMapping&& mapping);

  ~MallocMapping() override;

  /// Copies the data from `begin` to `end`.
  /// It's templated since void* arithemetic isn't allowed and we want support
  /// for `uint8_t` and `char`.
  template <typename T>
  static MallocMapping Copy(const T* begin, const T* end) {
    FML_DCHECK(end > begin);
    size_t length = end - begin;
    return Copy(begin, length);
  }

  /// Copies a region of memory into a MallocMapping.
  /// The function will `abort()` if the malloc fails.
  /// @param begin The starting address of where we will copy.
  /// @param length The length of the region to copy in bytes.
  static MallocMapping Copy(const void* begin, size_t length);

  // |Mapping|
  size_t GetSize() const override;

  // |Mapping|
  const uint8_t* GetMapping() const override;

  // |Mapping|
  bool IsDontNeedSafe() const override;

  /// Removes ownership of the data buffer.
  /// After this is called; the mapping will point to nullptr.
  [[nodiscard]] uint8_t* Release();

 private:
  uint8_t* data_;
  size_t size_;

  FML_DISALLOW_COPY_AND_ASSIGN(MallocMapping);
};

class SymbolMapping final : public Mapping {
 public:
  SymbolMapping(fml::RefPtr<fml::NativeLibrary> native_library,
                const char* symbol_name);

  ~SymbolMapping() override;

  // |Mapping|
  size_t GetSize() const override;

  // |Mapping|
  const uint8_t* GetMapping() const override;

  // |Mapping|
  bool IsDontNeedSafe() const override;

 private:
  fml::RefPtr<fml::NativeLibrary> native_library_;
  const uint8_t* mapping_ = nullptr;

  FML_DISALLOW_COPY_AND_ASSIGN(SymbolMapping);
};

}  // namespace fml

#endif  // FLUTTER_FML_MAPPING_H_
