/* Copyright 2017 - 2024 R. Thomas
 * Copyright 2017 - 2024 Quarkslab
 *
 * 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 "MachO/pyMachO.hpp"
#include "LIEF/MachO/enums.hpp"
#include "LIEF/MachO/EnumToString.hpp"
#include "LIEF/MachO/DyldChainedFormat.hpp"

#include "enums_wrapper.hpp"

#define PY_ENUM(x) to_string(x), x

namespace LIEF::MachO::py {
void init_enums(nb::module_& m) {

  enum_<MACHO_TYPES>(m, "MACHO_TYPES")
    .value(PY_ENUM(MACHO_TYPES::MH_MAGIC))
    .value(PY_ENUM(MACHO_TYPES::MH_CIGAM))
    .value(PY_ENUM(MACHO_TYPES::MH_MAGIC_64))
    .value(PY_ENUM(MACHO_TYPES::MH_CIGAM_64))
    .value(PY_ENUM(MACHO_TYPES::FAT_MAGIC))
    .value(PY_ENUM(MACHO_TYPES::FAT_CIGAM))
    .value(PY_ENUM(MACHO_TYPES::NEURAL_MODEL))
  ;

  enum_<X86_RELOCATION>(m, "X86_RELOCATION")
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_VANILLA))
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_PAIR))
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_SECTDIFF))
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_PB_LA_PTR))
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_LOCAL_SECTDIFF))
    .value(PY_ENUM(X86_RELOCATION::GENERIC_RELOC_TLV));

  enum_<X86_64_RELOCATION>(m, "X86_64_RELOCATION")
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_UNSIGNED))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_SIGNED))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_BRANCH))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_GOT_LOAD))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_GOT))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_SUBTRACTOR))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_SIGNED_1))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_SIGNED_2))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_SIGNED_4))
    .value(PY_ENUM(X86_64_RELOCATION::X86_64_RELOC_TLV));

  enum_<PPC_RELOCATION>(m, "PPC_RELOCATION")
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_VANILLA))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_PAIR))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_BR14))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_BR24))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_HI16))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_LO16))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_HA16))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_LO14))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_SECTDIFF))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_PB_LA_PTR))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_HI16_SECTDIFF))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_LO16_SECTDIFF))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_HA16_SECTDIFF))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_JBSR))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_LO14_SECTDIFF))
    .value(PY_ENUM(PPC_RELOCATION::PPC_RELOC_LOCAL_SECTDIFF));

  enum_<ARM_RELOCATION>(m, "ARM_RELOCATION")
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_VANILLA))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_PAIR))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_SECTDIFF))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_LOCAL_SECTDIFF))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_PB_LA_PTR))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_BR24))
    .value(PY_ENUM(ARM_RELOCATION::ARM_THUMB_RELOC_BR22))
    .value(PY_ENUM(ARM_RELOCATION::ARM_THUMB_32BIT_BRANCH))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_HALF))
    .value(PY_ENUM(ARM_RELOCATION::ARM_RELOC_HALF_SECTDIFF));

  enum_<ARM64_RELOCATION>(m, "ARM64_RELOCATION")
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_UNSIGNED))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_SUBTRACTOR))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_BRANCH26))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_PAGE21))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_PAGEOFF12))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_GOT_LOAD_PAGE21))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_GOT_LOAD_PAGEOFF12))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_POINTER_TO_GOT))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_TLVP_LOAD_PAGE21))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_TLVP_LOAD_PAGEOFF12))
    .value(PY_ENUM(ARM64_RELOCATION::ARM64_RELOC_ADDEND));

  enum_<DYLD_CHAINED_FORMAT>(m, "DYLD_CHAINED_FORMAT")
    .value(PY_ENUM(DYLD_CHAINED_FORMAT::IMPORT))
    .value(PY_ENUM(DYLD_CHAINED_FORMAT::IMPORT_ADDEND))
    .value(PY_ENUM(DYLD_CHAINED_FORMAT::IMPORT_ADDEND64));

  enum_<DYLD_CHAINED_PTR_FORMAT>(m, "DYLD_CHAINED_PTR_FORMAT")
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::NONE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_ARM64E))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_64))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_32))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_32_CACHE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_32_FIRMWARE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_64_OFFSET))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_ARM64E_KERNEL))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_64_KERNEL_CACHE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_ARM64E_USERLAND))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_ARM64E_FIRMWARE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_X86_64_KERNEL_CACHE))
    .value(PY_ENUM(DYLD_CHAINED_PTR_FORMAT::PTR_ARM64E_USERLAND24));

}
}
