# encoding: utf-8

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

require_relative "cert_g2_workaround"

def log_macos_signing_debug(keychain_name, label)
  UI.message("🔍 [#{label}] Code signing identities in temp keychain:")
  identities = `security find-identity -v -p codesigning "#{keychain_name}" 2>&1`
  UI.message(identities.empty? ? "(no output)" : identities)
end

def configure_keychain_for_codesign(keychain_name, keychain_password)
  UI.message("🔐 Setting key partition list for codesign tools...")
  begin
    sh("security", "set-key-partition-list", "-S", "apple-tool:,apple:,codesign:", "-s", "-k", keychain_password, keychain_name)
    UI.message("✅ Key partition list updated.")
  rescue => e
    UI.message("ℹ️ set-key-partition-list skipped: #{e.message}")
  end
end

lane :build_macos_pre do
  full_project_dir = ENV["FULL_PROJECT_DIR"]
  if full_project_dir == nil
    UI.user_error!("Environment variable FULL_PROJECT_DIR is missing.")
  end
  UI.message("ℹ️ The directory of the current application is: #{full_project_dir}")

  build_number = ENV["NEW_BUILD"]
  version_number = ENV["NEW_STORE_VERSION"] || ENV["NEW_VERSION"]

  default_keychain_name = ENV['DEFAULT_KEYCHAIN_NAME']
  default_keychain_password = ENV['DEFAULT_KEYCHAIN_PASSWORD']
  import_certificate_path = "../ios/AppleWWDRCA.cer"

  developer_team_id = ENV['APP_STORE_CONNECT_DEVELOPER_TEAM_ID']

  app_store_key_id = ENV['APP_STORE_CONNECT_KEY_ID']
  app_store_issuer_id = ENV['APP_STORE_CONNECT_KEY_ISSUER_ID']
  app_store_key_path = ENV['APP_STORE_CONNECT_KEY_PATH']

  app_identifier = ENV['MACOS_APP_IDENTIFIER']

  match_git_username = ENV['FASTLANE_MATCH_BOT_USERNAME']
  match_git_fullname = ENV['FASTLANE_MATCH_BOT_FULLNAME']
  match_git_email = ENV['FASTLANE_MATCH_BOT_EMAIL']
  match_git_url = ENV['FASTLANE_MATCH_GIT_HTTP_URL']
  match_git_basic_authorization = ENV['FASTLANE_MATCH_GIT_BASIC_AUTHORIZATION']
  if match_git_url.nil? || match_git_url.empty?
    match_git_path = ENV['FASTLANE_MATCH_GITLAB_PROJECT_PATH']
    if match_git_path.nil? || match_git_path.empty?
      UI.user_error!("Environment variable FASTLANE_MATCH_GIT_HTTP_URL or FASTLANE_MATCH_GITLAB_PROJECT_PATH is missing.")
    end
    match_git_url = "https://gitlab.application-platform.com/#{match_git_path}.git"
  end

  if build_number == nil
    UI.user_error!("Environment variable NEW_BUILD is missing.")
  end
  if version_number == nil
    UI.user_error!("Environment variable NEW_VERSION is missing.")
  end
  if default_keychain_name == nil
    UI.user_error!("Environment variable DEFAULT_KEYCHAIN_NAME is missing.")
  end
  if default_keychain_password == nil
    UI.user_error!("Environment variable DEFAULT_KEYCHAIN_PASSWORD is missing.")
  end
  if developer_team_id == nil
    UI.user_error!("Environment variable APP_STORE_CONNECT_DEVELOPER_TEAM_ID is missing.")
  end
  if app_store_key_id == nil
    UI.user_error!("Environment variable APP_STORE_CONNECT_KEY_ID is missing.")
  end
  if app_store_issuer_id == nil
    UI.user_error!("Environment variable APP_STORE_CONNECT_KEY_ISSUER_ID is missing.")
  end
  if app_store_key_path == nil
    UI.user_error!("Environment variable APP_STORE_CONNECT_KEY_PATH is missing.")
  end
  if app_identifier == nil
    UI.user_error!("Environment variable MACOS_APP_IDENTIFIER is missing.")
  end
  if match_git_basic_authorization == nil || match_git_basic_authorization.empty?
    UI.user_error!("Environment variable FASTLANE_MATCH_GIT_BASIC_AUTHORIZATION is missing.")
  end
  if match_git_username == nil
    UI.user_error!("Environment variable FASTLANE_MATCH_BOT_USERNAME is missing.")
  end
  if match_git_fullname == nil
    UI.user_error!("Environment variable FASTLANE_MATCH_BOT_FULLNAME is missing.")
  end
  if match_git_email == nil
    UI.user_error!("Environment variable FASTLANE_MATCH_BOT_EMAIL is missing.")
  end

  UI.message("🚀 Unlocking keychain and importing certificates...")
  UI.message("ℹ️ Temp keychain path: #{default_keychain_name}")
  unlock_keychain(
    path: default_keychain_name,
    password: default_keychain_password,
    add_to_search_list: true,
    set_default: true
  )
  log_macos_signing_debug(default_keychain_name, "after unlock_keychain")

  if File.exist?(import_certificate_path)
    UI.message("🚀 Importing Apple WWDRCA certificate...")
    import_certificate(
      certificate_path: import_certificate_path,
      keychain_name: default_keychain_name,
      keychain_password: default_keychain_password,
      log_output: true
    )
  else
    UI.message("⚠️ Apple WWDRCA certificate not found at #{import_certificate_path}; continuing.")
  end

  UI.message("🚀 Syncing Developer ID code signing for #{app_identifier}...")
  api_key = app_store_connect_api_key(
    key_id: app_store_key_id,
    issuer_id: app_store_issuer_id,
    key_filepath: app_store_key_path,
    duration: 1200,
    in_house: false
  )

  max_retries = 3
  attempt = 0

  begin
    attempt += 1
    UI.message("🚀 Syncing certificates from match repository... (Versuch #{attempt}/#{max_retries})")
    sync_code_signing(
      api_key: api_key,
      type: "developer_id",
      platform: "macos",
      app_identifier: app_identifier,
      readonly: true,
      output_path: "./builds",
      keychain_name: default_keychain_name,
      keychain_password: default_keychain_password,
      team_id: developer_team_id,
      git_branch: developer_team_id,
      git_url: match_git_url,
      git_basic_authorization: match_git_basic_authorization,
      git_full_name: match_git_fullname,
      git_user_email: match_git_email,
      storage_mode: "git",
      verbose: true
    )
  rescue => e
    if attempt < max_retries
      UI.error("❌ Fehler beim Sync (Versuch #{attempt}): #{e.message}")
      UI.message("🔁 Neuer Versuch in 5 Sekunden...")
      sleep 5
      retry
    else
      UI.user_error!("🚨 Sync ist nach #{max_retries} Versuchen fehlgeschlagen: #{e.message}")
    end
  end

  configure_keychain_for_codesign(default_keychain_name, default_keychain_password)
  log_macos_signing_debug(default_keychain_name, "after match sync")

  UI.message("🚀 Setting up Xcode project for macOS release...")
  update_code_signing_settings(
    profile_name: "match Direct #{app_identifier} macos",
    build_configurations: "Release",
    code_sign_identity: "Developer ID Application",
    use_automatic_signing: false,
    targets: "Runner",
  )

  increment_build_number(
    build_number: build_number,
    xcodeproj: "Runner.xcodeproj"
  )

  increment_version_number(
    version_number: version_number,
    xcodeproj: "Runner.xcodeproj"
  )

  update_project_team(
    teamid: developer_team_id
  )

  UI.success("✅ macOS Xcode project prepared (certificates via Match).")
end

# Legacy/local lane — CI uses `dart run dmg` for sign, notarize, and DMG creation.
lane :notarize_macos do
  app_path = ENV["MACOS_APP_PATH"]
  app_identifier = ENV['MACOS_APP_IDENTIFIER']
  app_store_key_id = ENV['APP_STORE_CONNECT_KEY_ID']
  app_store_issuer_id = ENV['APP_STORE_CONNECT_KEY_ISSUER_ID']
  app_store_key_path = ENV['APP_STORE_CONNECT_KEY_PATH']

  if app_path == nil || !File.exist?(app_path)
    UI.user_error!("MACOS_APP_PATH is missing or does not exist: #{app_path}")
  end
  if app_identifier == nil
    UI.user_error!("Environment variable MACOS_APP_IDENTIFIER is missing.")
  end

  api_key = app_store_connect_api_key(
    key_id: app_store_key_id,
    issuer_id: app_store_issuer_id,
    key_filepath: app_store_key_path,
    duration: 1200,
    in_house: false
  )

  zip_path = File.join(Dir.tmpdir, "macos-notarize-#{Process.pid}.zip")
  app_dir = File.dirname(app_path)
  app_name = File.basename(app_path)
  UI.message("🚀 Creating notarization archive at #{zip_path}...")
  Dir.chdir(app_dir) do
    sh("zip", "-r", "-y", zip_path, app_name)
  end
  unless File.exist?(zip_path)
    UI.user_error!("Notarization zip was not created at #{zip_path}")
  end

  UI.message("🚀 Submitting app for notarization...")
  notarize(
    api_key: api_key,
    bundle_id: app_identifier,
    package: zip_path,
    print_log: true,
    use_notarytool: true,
    skip_stapling: true
  )

  UI.message("🚀 Stapling notarization ticket to app bundle...")
  sh("xcrun", "stapler", "staple", app_path)

  File.delete(zip_path) if File.exist?(zip_path)
  UI.success("✅ macOS app notarized and stapled.")
end
