# This file contains the fastlane.tools configuration for the PediFoods iOS app.
# You can find the documentation at https://docs.fastlane.tools

require "date"
require "json"
require "fileutils"

default_platform(:ios)

# Build number scheme: "YYYY.MM.DD.0.0.<n>" - <n> increments across
# builds made on the same calendar day, resets to 1 on a new day.
# Needs somewhere to remember "the last <n> used, and for which day",
# and the per-run checkout under .cache/act/<random-hash>/ can't be
# that place - each CI run gets a fresh, throwaway clone, so anything
# written there is gone by the next run. State lives instead at a fixed
# path under this CI user's home directory on the Mac mini runner,
# which is the same machine/user across every run.
def next_build_version
  state_path = File.expand_path("~/ci-build-version-state/pedifoods.json")
  FileUtils.mkdir_p(File.dirname(state_path))

  today = Date.today.strftime("%Y.%m.%d")
  state = File.exist?(state_path) ? JSON.parse(File.read(state_path)) : {}
  build_number = (state["date"] == today) ? state["build_number"].to_i + 1 : 1

  File.write(state_path, JSON.generate({ "date" => today, "build_number" => build_number }))
  "#{today}.0.0.#{build_number}"
end

lane :tests do
  run_tests(
    scheme: "PediFoods",
    project: "PediFoods.xcodeproj",
    clean: true,
    code_coverage: true
  )
end

lane :assemble do |options|
  # Manual signing (team/identity/profile) for the "PediFoods" target is
  # baked directly into PediFoods.xcodeproj's own project settings - not
  # overridden here.
  #
  # CURRENT_PROJECT_VERSION IS overridden here, with next_build_version
  # (see top of file) rather than the project's own committed value.
  # Earlier versions of this lane either used the committed value as-is
  # (fine until you forget to bump it and Apple rejects a duplicate
  # build number) or overrode it with the CI job's raw run-number
  # counter (BUILD_NUMBER = github.run_number-style, which silently
  # uploaded a build as "51" with no relation to the real version at
  # all). next_build_version keeps the real date-based scheme and
  # bumps only the last component automatically, so every push
  # is guaranteed a fresh, correctly-formatted, ever-increasing build
  # number with no manual edit needed before each run.
  xcargs = "-skipPackagePluginValidation -skipMacroValidation CURRENT_PROJECT_VERSION=#{next_build_version}"

  build_app(
    scheme: "PediFoods",
    sdk: "iphoneos",
    export_method: "app-store",
    xcconfig: "fastlane/AppStore.xcconfig",
    xcargs: xcargs,
    derived_data_path: ".build/DerivedData",
    output_directory: ".build/fastlane",
    skip_archive: ENV["FASTLANE_SKIP_ARCHIVE"] == "YES",
    skip_codesigning: ENV["FASTLANE_SKIP_CODESIGNING"] == "YES"
  )
end

# Manual signing (PROVISIONING_PROFILE_SPECIFIER baked directly into
# PediFoods.xcodeproj's build settings, per target) means Xcode resolves
# a profile by matching that exact Name string against installed
# .mobileprovision files - not by bundle identifier alone. Without an
# explicit provisioning_name:, sigh names a freshly (re)created profile
# "<bundle identifier> AppStore" by default, which doesn't match the
# project's expected names ("LC Prov PediFoods Dist Profile" / "LC Prov
# PediFoods Dist Push Profile") - Xcode then can't find it and falls
# back to whatever stale profile happens to already be installed under
# the old name, which is exactly the doesn't-include-this-cert error
# force: true alone didn't fix. Also needs one call per target: sigh
# only touches the app_identifier it's given, and the
# NotificationServiceExtension has its own separate bundle id.
private_lane :renew_provisioning_profiles do
  get_provisioning_profile(
    api_key_path: "fastlane/apikey.json",
    app_identifier: "com.br.pedifoods.app",
    provisioning_name: "LC Prov PediFoods Dist Profile",
    force: true
  )
  get_provisioning_profile(
    api_key_path: "fastlane/apikey.json",
    app_identifier: "com.br.pedifoods.app.NotificationService",
    provisioning_name: "LC Prov PediFoods Dist Push Profile",
    force: true
  )
end

lane :beta do |options|
  desc "Build and upload to TestFlight"

  renew_provisioning_profiles

  assemble

  upload_to_testflight(
    api_key_path: "fastlane/apikey.json",
    skip_waiting_for_build_processing: true
  )
end

lane :release do |options|
  desc "Build and release app"

  # see https://docs.fastlane.tools/uploading-app-privacy-details/
  #upload_app_privacy_details_to_app_store(json_path: "fastlane/app_privacy_details.json")

  # if you have an apikey.json file (https://developer.apple.com/documentation/appstoreconnectapi/creating-api-keys-for-app-store-connect-api), fastlane can automatically fetch certificates and the ASC authentication information
  #get_certificates(api_key_path: "fastlane/apikey.json")
  renew_provisioning_profiles

  assemble

  upload_to_app_store(
    api_key_path: "fastlane/apikey.json",
    app_rating_config_path: "fastlane/metadata/rating.json",
    release_notes: { default: "Fixes and improvements." },
    submit_for_review: false
  )
end

