# SPDX-License-Identifier: Apache-2.0
# ---------------------------------------------------------------------------
# FIPS-compliant SQLCipher cross-platform build pipeline.
# Supports Android (NDK) and iOS (Xcode) targets.
#
# Platform selection:
#   -DTARGET_PLATFORM=Android   (default) NDK cross-compile, shared libs
#   -DTARGET_PLATFORM=iOS       Xcode cross-compile, static libs
#
# Developer mode (probe code warnings + compile_commands.json):
#   -DFIPS_DEVELOPER_MODE=ON
# ---------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.22)

project(fips_sqlcipher
  VERSION 1.0.0
  DESCRIPTION "FIPS-compliant SQLCipher orchestration for mobile targets"
  LANGUAGES C
)

# ---------------------------------------------------------------------------
# Options and cache variables
# ---------------------------------------------------------------------------
set(TARGET_PLATFORM "Android" CACHE STRING "Target platform: Android or iOS")
set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS "Android" "iOS")

set(OPENSSL_VERSION   "3.1.2"   CACHE STRING "OpenSSL FIPS source version")
set(SQLCIPHER_VERSION "v4.6.1"  CACHE STRING "SQLCipher release tag")

option(FIPS_DEVELOPER_MODE "Enable warnings and compile_commands.json for in-project code" OFF)

# ---------------------------------------------------------------------------
# Developer mode: compile_commands.json for LSP/static analysis
# ---------------------------------------------------------------------------
if(FIPS_DEVELOPER_MODE)
  set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()

# ---------------------------------------------------------------------------
# Module path and shared infrastructure
# ---------------------------------------------------------------------------
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
include(ExternalProject)
include(FIPSConfig)

# ---------------------------------------------------------------------------
# Dist layout (shared structure, platform-specific prefix)
# ---------------------------------------------------------------------------
set(DIST_ROOT "${PROJECT_SOURCE_DIR}/dist")

# ===========================================================================
# ANDROID
# ===========================================================================
if(TARGET_PLATFORM STREQUAL "Android")

  set(ANDROID_ABI       "arm64-v8a"   CACHE STRING "Target Android ABI")
  set(ANDROID_PLATFORM  "android-24"  CACHE STRING "Minimum Android API level")

  if(NOT ANDROID_NDK AND DEFINED ENV{ANDROID_NDK_ROOT})
    set(ANDROID_NDK "$ENV{ANDROID_NDK_ROOT}" CACHE PATH "Android NDK root")
  endif()
  if(NOT ANDROID_NDK OR NOT EXISTS "${ANDROID_NDK}")
    message(FATAL_ERROR
      "ANDROID_NDK is not set or does not exist. "
      "Export ANDROID_NDK_ROOT or pass -DANDROID_NDK=/path/to/ndk.")
  endif()

  set(DIST_ABI_DIR      "${DIST_ROOT}/${ANDROID_ABI}")
  set(DIST_LIB_DIR      "${DIST_ABI_DIR}/lib")
  set(DIST_INCLUDE_DIR  "${DIST_ABI_DIR}/include")
  set(DIST_FIPS_DIR     "${DIST_ABI_DIR}/fips")
  file(MAKE_DIRECTORY
    "${DIST_LIB_DIR}" "${DIST_INCLUDE_DIR}" "${DIST_FIPS_DIR}")

  include(PreserveFipsIntegrity)
  include(BuildOpenSSL)
  include(BuildSQLCipher)

  add_custom_target(fips_sqlcipher ALL
    DEPENDS sqlcipher_ep
    COMMAND ${CMAKE_COMMAND} -E echo ""
    COMMAND ${CMAKE_COMMAND} -E echo "FIPS SQLCipher pipeline complete [Android]"
    COMMAND ${CMAKE_COMMAND} -E echo "  ABI:       ${ANDROID_ABI}"
    COMMAND ${CMAKE_COMMAND} -E echo "  API:       ${ANDROID_PLATFORM}"
    COMMAND ${CMAKE_COMMAND} -E echo "  OpenSSL:   ${OPENSSL_VERSION}"
    COMMAND ${CMAKE_COMMAND} -E echo "  SQLCipher: ${SQLCIPHER_VERSION}"
    COMMAND ${CMAKE_COMMAND} -E echo "  Artifacts: ${DIST_ABI_DIR}"
  )

  message(STATUS "FIPS SQLCipher [Android] configuration:")
  message(STATUS "  ANDROID_NDK          = ${ANDROID_NDK}")
  message(STATUS "  CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}")
  message(STATUS "  ANDROID_ABI          = ${ANDROID_ABI}")
  message(STATUS "  ANDROID_PLATFORM     = ${ANDROID_PLATFORM}")
  message(STATUS "  OPENSSL_VERSION      = ${OPENSSL_VERSION}")
  message(STATUS "  SQLCIPHER_VERSION    = ${SQLCIPHER_VERSION}")
  message(STATUS "  FIPS_PARALLEL_JOBS   = ${FIPS_PARALLEL_JOBS}")
  message(STATUS "  DIST_ABI_DIR         = ${DIST_ABI_DIR}")

# ===========================================================================
# iOS
# ===========================================================================
elseif(TARGET_PLATFORM STREQUAL "iOS")

  set(IOS_ARCH              "arm64"  CACHE STRING "Target arch: arm64 or x86_64")
  set(IOS_PLATFORM          "OS"     CACHE STRING "OS (device) or SIMULATOR")
  set(IOS_DEPLOYMENT_TARGET "15.0"   CACHE STRING "Minimum iOS version")
  set_property(CACHE IOS_PLATFORM PROPERTY STRINGS "OS" "SIMULATOR")

  if(IOS_PLATFORM STREQUAL "OS")
    set(_sdk_name "iphoneos")
    set(_slice_name "ios-${IOS_ARCH}")
  else()
    set(_sdk_name "iphonesimulator")
    set(_slice_name "ios-simulator-${IOS_ARCH}")
  endif()

  execute_process(
    COMMAND xcrun --sdk ${_sdk_name} --show-sdk-path
    OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
    OUTPUT_STRIP_TRAILING_WHITESPACE
    RESULT_VARIABLE _xcrun_rc
  )
  if(NOT _xcrun_rc EQUAL 0)
    message(FATAL_ERROR
      "xcrun --sdk ${_sdk_name} --show-sdk-path failed. "
      "Install Xcode Command Line Tools: xcode-select --install")
  endif()

  set(DIST_ABI_DIR      "${DIST_ROOT}/${_slice_name}")
  set(DIST_LIB_DIR      "${DIST_ABI_DIR}/lib")
  set(DIST_INCLUDE_DIR  "${DIST_ABI_DIR}/include")
  set(DIST_FIPS_DIR     "${DIST_ABI_DIR}/fips")
  file(MAKE_DIRECTORY
    "${DIST_LIB_DIR}" "${DIST_INCLUDE_DIR}" "${DIST_FIPS_DIR}")

  include(BuildOpenSSL_iOS)
  include(BuildSQLCipher_iOS)

  add_custom_target(fips_sqlcipher_ios ALL
    DEPENDS sqlcipher_ios_ep
    COMMAND ${CMAKE_COMMAND} -E echo ""
    COMMAND ${CMAKE_COMMAND} -E echo "FIPS SQLCipher pipeline complete [iOS]"
    COMMAND ${CMAKE_COMMAND} -E echo "  Arch:      ${IOS_ARCH}"
    COMMAND ${CMAKE_COMMAND} -E echo "  Platform:  ${IOS_PLATFORM}"
    COMMAND ${CMAKE_COMMAND} -E echo "  Min iOS:   ${IOS_DEPLOYMENT_TARGET}"
    COMMAND ${CMAKE_COMMAND} -E echo "  OpenSSL:   ${OPENSSL_VERSION}"
    COMMAND ${CMAKE_COMMAND} -E echo "  SQLCipher: ${SQLCIPHER_VERSION}"
    COMMAND ${CMAKE_COMMAND} -E echo "  Artifacts: ${DIST_ABI_DIR}"
  )

  message(STATUS "FIPS SQLCipher [iOS] configuration:")
  message(STATUS "  IOS_ARCH              = ${IOS_ARCH}")
  message(STATUS "  IOS_PLATFORM          = ${IOS_PLATFORM}")
  message(STATUS "  IOS_DEPLOYMENT_TARGET = ${IOS_DEPLOYMENT_TARGET}")
  message(STATUS "  CMAKE_OSX_SYSROOT     = ${CMAKE_OSX_SYSROOT}")
  message(STATUS "  OPENSSL_VERSION       = ${OPENSSL_VERSION}")
  message(STATUS "  SQLCIPHER_VERSION     = ${SQLCIPHER_VERSION}")
  message(STATUS "  FIPS_PARALLEL_JOBS    = ${FIPS_PARALLEL_JOBS}")
  message(STATUS "  DIST_ABI_DIR          = ${DIST_ABI_DIR}")

else()
  message(FATAL_ERROR
    "Unknown TARGET_PLATFORM: '${TARGET_PLATFORM}'. "
    "Valid values: Android, iOS.")
endif()

# ===========================================================================
# Install / Export (allows find_package(FIPSSQLCipher) by downstream projects)
# ===========================================================================
include(CMakePackageConfigHelpers)

install(DIRECTORY "${DIST_ABI_DIR}/lib/"
  DESTINATION lib
  FILES_MATCHING
    PATTERN "*.so"
    PATTERN "*.a"
    PATTERN "*.dylib"
)
install(DIRECTORY "${DIST_ABI_DIR}/include/"
  DESTINATION include
)
install(DIRECTORY "${DIST_ABI_DIR}/fips/"
  DESTINATION share/fips-sqlcipher/fips
)
install(FILES "${PROJECT_SOURCE_DIR}/include/fips_sqlcipher.h"
              "${PROJECT_SOURCE_DIR}/include/fips_verify.hpp"
  DESTINATION include
)

configure_package_config_file(
  "${PROJECT_SOURCE_DIR}/cmake/FIPSSQLCipherConfig.cmake.in"
  "${CMAKE_BINARY_DIR}/FIPSSQLCipherConfig.cmake"
  INSTALL_DESTINATION lib/cmake/FIPSSQLCipher
)
write_basic_package_version_file(
  "${CMAKE_BINARY_DIR}/FIPSSQLCipherConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)
install(FILES
  "${CMAKE_BINARY_DIR}/FIPSSQLCipherConfig.cmake"
  "${CMAKE_BINARY_DIR}/FIPSSQLCipherConfigVersion.cmake"
  DESTINATION lib/cmake/FIPSSQLCipher
)
