# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do
  # Constants
  TEAM_ID = "2W7AC6T8T5"
  CODE_SIGN_IDENTITY = "Apple Distribution: FUTO Holdings, Inc. (#{TEAM_ID})"
  BASE_BUNDLE_ID = "app.alextran.immich"
  DEV_BUNDLE_ID  = "tech.futo.immich.testflight"
  DEV_GROUP_ID   = "group.app.immich.share.testflight"

  # Helper method to get App Store Connect API key
  def get_api_key
    app_store_connect_api_key(
      key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],
      issuer_id: ENV["APP_STORE_CONNECT_API_KEY_ISSUER_ID"],
      key_filepath: "#{Dir.home}/.appstoreconnect/private_keys/AuthKey_#{ENV['APP_STORE_CONNECT_API_KEY_ID']}.p8",
      duration: 1200,
      in_house: false
    )
  end
  
  # Helper method to assemble xcargs with optional CUSTOM_GROUP_ID override
  def build_xcargs(group_id: nil)
    args = "-skipMacroValidation CODE_SIGN_IDENTITY='#{CODE_SIGN_IDENTITY}' CODE_SIGN_STYLE=Manual"
    args += " CUSTOM_GROUP_ID='#{group_id}'" if group_id
    args
  end

  # Helper method to get version from pubspec.yaml
def get_version_from_pubspec
  require 'yaml'
  
  pubspec_path = File.join(Dir.pwd, "../..", "pubspec.yaml")
  pubspec = YAML.load_file(pubspec_path)
  
  version_string = pubspec['version']
  version_string ? version_string.split('+').first.split('-').first : nil
end
  
  # Helper method to configure code signing for all targets
  def configure_code_signing(base_bundle_id:, profile_name_main:, profile_name_share:, profile_name_widget:)
    # Runner (main app)
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: base_bundle_id,
      profile_name: profile_name_main,
      targets: ["Runner"]
    )

    # ShareExtension
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: "#{base_bundle_id}.ShareExtension",
      profile_name: profile_name_share,
      targets: ["ShareExtension"]
    )

    # WidgetExtension
    update_code_signing_settings(
      use_automatic_signing: false,
      path: "./Runner.xcodeproj",
      team_id: ENV["FASTLANE_TEAM_ID"] || TEAM_ID,
      code_sign_identity: CODE_SIGN_IDENTITY,
      bundle_identifier: "#{base_bundle_id}.Widget",
      profile_name: profile_name_widget,
      targets: ["WidgetExtension"]
    )
  end

  # Helper method to build and upload to TestFlight
  def build_and_upload(
    api_key:,
    base_bundle_id:,
    configuration: "Release",
    distribute_external: true,
    version_number: nil,
    profile_name_main:,
    profile_name_share:,
    profile_name_widget:,
    group_id: nil
  )
    app_identifier = base_bundle_id

    # Set version number if provided
    if version_number
      increment_version_number(version_number: version_number)
    end

    # Increment build number
    increment_build_number(
      build_number: latest_testflight_build_number(
        api_key: api_key,
        app_identifier: app_identifier
      ) + 1,
      xcodeproj: "./Runner.xcodeproj"
    )

    # Build the app
    build_app(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: configuration,
      export_method: "app-store",
      xcargs: build_xcargs(group_id: group_id),
      export_options: {
        provisioningProfiles: {
          "#{app_identifier}" => profile_name_main,
          "#{app_identifier}.ShareExtension" => profile_name_share,
          "#{app_identifier}.Widget" => profile_name_widget
        },
        signingStyle: "manual",
        signingCertificate: CODE_SIGN_IDENTITY
      }
    )
    
    # Upload to TestFlight
    upload_to_testflight(
      api_key: api_key,
      skip_waiting_for_build_processing: true,
      distribute_external: distribute_external
    )
  end
  
  desc "iOS Development Build to TestFlight (requires separate bundle ID)"
  lane :gha_testflight_dev do
    api_key = get_api_key

    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    # Capture profile names after each sigh call
    sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]

    sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]

    sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]

    # Configure code signing for dev bundle IDs using the downloaded profile names
    configure_code_signing(
      base_bundle_id: DEV_BUNDLE_ID,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )

    # Build and upload
    build_and_upload(
      api_key: api_key,
      base_bundle_id: DEV_BUNDLE_ID,
      configuration: "Profile",
      distribute_external: false,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name,
      group_id: DEV_GROUP_ID
    )
  end

  desc "iOS Release to TestFlight"
  lane :gha_release_prod do
    api_key = get_api_key
    
    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    sigh(api_key: api_key, app_identifier: BASE_BUNDLE_ID, force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    sigh(api_key: api_key, app_identifier: "#{BASE_BUNDLE_ID}.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]
    
    
    # Configure code signing for production bundle IDs
    configure_code_signing(
      base_bundle_id: BASE_BUNDLE_ID,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )

    # Build and upload with version number
    build_and_upload(
      api_key: api_key,
      base_bundle_id: BASE_BUNDLE_ID,
      version_number: get_version_from_pubspec,
      distribute_external: false,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )
  end

  desc "iOS Manual Release"
  lane :release_manual do
    enable_automatic_code_signing(
      path: "./Runner.xcodeproj",
      targets: ["Runner", "ShareExtension", "WidgetExtension"]
    )

    increment_version_number(
      version_number: get_version_from_pubspec
    )
    increment_build_number(
      build_number: latest_testflight_build_number + 1,
    )
    
    # Build archive with automatic signing
    gym(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: "Release",
      export_method: "app-store",
      skip_package_ipa: false,
      xcargs: "-skipMacroValidation -allowProvisioningUpdates",
      export_options: {
        method: "app-store",
        signingStyle: "automatic",
        uploadBitcode: false,
        uploadSymbols: true,
        compileBitcode: false
      }
    )
    
    upload_to_testflight(
      skip_waiting_for_build_processing: true
    )
  end

  desc "iOS Build Only (no TestFlight upload)"
  lane :gha_build_only do
    # Use the same build process as the dev TestFlight lane, just skip the upload
    # This ensures PR builds validate the same way as dev TestFlight builds

    api_key = get_api_key

    # Download and install provisioning profiles from App Store Connect
    # Certificate is imported by GHA workflow into build.keychain
    sigh(api_key: api_key, app_identifier: DEV_BUNDLE_ID, force: true)
    main_profile_name = lane_context[SharedValues::SIGH_NAME]

    sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.ShareExtension", force: true)
    share_profile_name = lane_context[SharedValues::SIGH_NAME]

    sigh(api_key: api_key, app_identifier: "#{DEV_BUNDLE_ID}.Widget", force: true)
    widget_profile_name = lane_context[SharedValues::SIGH_NAME]

    # Configure code signing for dev bundle IDs
    configure_code_signing(
      base_bundle_id: DEV_BUNDLE_ID,
      profile_name_main: main_profile_name,
      profile_name_share: share_profile_name,
      profile_name_widget: widget_profile_name
    )

    # Build the app (same as gha_testflight_dev but without upload)
    build_app(
      scheme: "Runner",
      workspace: "Runner.xcworkspace",
      configuration: "Release",
      export_method: "app-store",
      skip_package_ipa: true,
      xcargs: build_xcargs(group_id: DEV_GROUP_ID),
      export_options: {
        provisioningProfiles: {
          DEV_BUNDLE_ID => main_profile_name,
          "#{DEV_BUNDLE_ID}.ShareExtension" => share_profile_name,
          "#{DEV_BUNDLE_ID}.Widget" => widget_profile_name
        },
        signingStyle: "manual",
        signingCertificate: CODE_SIGN_IDENTITY
      }
    )
  end

end
