fastlane_version "2.203.0"
skip_docs

ensure_env_vars(
  env_vars: ["ENVIRONMENT", "SENTRY_ORGANIZATION", "SENTRY_PROJECT", "SENTRY_AUTH_TOKEN"]
)

VERSIONS = read_json( json_path: "./package.json" )[:versions]
ENVIRONMENT = ENV["ENVIRONMENT"]
VERSION = "#{VERSIONS[:major]}.#{VERSIONS[:minor]}"
RELEASE_CHANNEL = "#{VERSIONS[:major]}.#{VERSIONS[:minor]}-#{ENVIRONMENT}"
BUILD_NUMBER = "#{Time.now.strftime("%y%m%d")}#{ENV["GITHUB_RUN_NUMBER"]}"
GITHUB_REPO = "tooot-app/app"
case ENVIRONMENT
when "candidate"
  GITHUB_RELEASE = "v#{VERSION}-#{VERSIONS[:patch]}"
when "release"
  GITHUB_RELEASE = "v#{VERSION}"
else
  GITHUB_RELEASE= ""
end

XCODEPROJ = "./ios/tooot.xcodeproj"
INFO_PLIST = "./ios/tooot/Info.plist"
EXPO_PLIST = "./ios/tooot/Supporting/Expo.plist"

desc "IOS: Prepare app store"
private_lane :prepare_appstore_ios do
  set_info_plist_value( path: INFO_PLIST, key: "CFBundleShortVersionString", value: VERSION )
  set_info_plist_value(
    path: INFO_PLIST,
    key: "NSAppTransportSecurity",
    value: {}
  )
  increment_build_number( xcodeproj: XCODEPROJ, build_number: BUILD_NUMBER )
  app_store_connect_api_key
end

desc 'IOS: Update expo information'
private_lane :update_expo_ios do
  set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesSDKVersion", value: VERSIONS[:expo] )
  set_info_plist_value( path: EXPO_PLIST, key: "EXUpdatesReleaseChannel", value: RELEASE_CHANNEL )
end

desc "ANDROID: Prepare play store"
private_lane :prepare_playstore_android do
  android_set_version_name( version_name: VERSION, gradle_file: "./android/app/build.gradle" )
  android_set_version_code( version_code: BUILD_NUMBER, gradle_file: "./android/app/build.gradle" )
end

desc "Create new GitHub release"
private_lane :github_release do |options|
  set_github_release(
    repository_name: GITHUB_REPO,
    name: GITHUB_RELEASE,
    tag_name: GITHUB_RELEASE,
    description: "No changelog provided",
    commitish: git_branch,
    is_prerelease: options[:prerelease],
    upload_assets: ["#{File.expand_path('..', Dir.pwd)}/tooot-#{GITHUB_RELEASE}.apk"]
  )
end

desc "Expo release"
private_lane :expo_release do
  yarn( package_path: "./package.json", flags: "release", command: RELEASE_CHANNEL )
end

desc "Build and deploy iOS app"
private_lane :build_ios do
  BUILD_DIRECTORY = "./ios/build"
  IPA_FILE = "#{BUILD_DIRECTORY}/tooot.ipa"
  DSYM_FILE = "#{BUILD_DIRECTORY}/tooot.app.dSYM.zip"

  update_expo_ios
  setup_ci

  case ENVIRONMENT
  when "candidate"
    prepare_appstore_ios
    match( type: "appstore", readonly: true )
    build_ios_app(
      export_method: "app-store",
      include_symbols: true,
      output_directory: BUILD_DIRECTORY,
      silent: true
    )
    sentry_upload_dsym(
      org_slug: ENV["SENTRY_ORGANIZATION"],
      project_slug: ENV["SENTRY_PROJECT"],
      dsym_path: DSYM_FILE
    )
    upload_to_testflight(
      skip_submission: true,
      ipa: IPA_FILE,
      demo_account_required: true,
      distribute_external: true,
      groups: "尝鲜",
      changelog: "感谢帮忙测试 tooot 🙏"
    )
  when "release"
    prepare_appstore_ios
    match( type: "appstore", readonly: true )
    build_ios_app(
      export_method: "app-store",
      include_bitcode: true,
      output_directory: BUILD_DIRECTORY,
      silent: true
    )
    upload_to_app_store( ipa: IPA_FILE, app_version: VERSION )
    download_dsyms( version: VERSION, build_number: BUILD_NUMBER, wait_for_dsym_processing: true )
    sentry_upload_dsym(
      org_slug: ENV["SENTRY_ORGANIZATION"],
      project_slug: ENV["SENTRY_PROJECT"],
    )
  else
    if !is_ci
      match( type: "adhoc", readonly: true )
      build_ios_app( export_method: "ad-hoc", output_directory: BUILD_DIRECTORY, silent: true )
      install_on_device( skip_wifi: true )
    end
  end
end

desc "Build and deploy Android app"
private_lane :build_android do
  sh("echo #{ENV["ANDROID_KEYSTORE"]} | base64 -d | tee #{File.expand_path('..', Dir.pwd)}/android/tooot.jks >/dev/null", log: false)

  case ENVIRONMENT
  when "candidate"
    prepare_playstore_android
    build_android_app(
      task: 'clean bundle',
      build_type: 'release',
      project_dir: "./android",
      print_command: true,
      print_command_output: true,
      properties: {
        "expoSDK" => VERSIONS[:expo],
        "releaseChannel" => RELEASE_CHANNEL,
        "android.injected.signing.store.file" => "#{File.expand_path('..', Dir.pwd)}/android/tooot.jks",
        "android.injected.signing.store.password" => ENV["ANDROID_KEYSTORE_PASSWORD"],
        "android.injected.signing.key.alias" => ENV["ANDROID_KEYSTORE_ALIAS"],
        "android.injected.signing.key.password" => ENV["ANDROID_KEYSTORE_KEY_PASSWORD"],
      }
    )
    upload_to_play_store(
      track: "alpha",
      skip_upload_metadata: true,
      skip_upload_changelogs: true,
      skip_upload_images: true,
      skip_upload_screenshots: true
    )
    build_android_app(
      task: 'assemble',
      build_type: 'release',
      project_dir: "./android",
      print_command: false,
      print_command_output: false,
      properties: {
        "expoSDK" => VERSIONS[:expo],
        "releaseChannel" => RELEASE_CHANNEL,
        "android.injected.signing.store.file" => "#{File.expand_path('..', Dir.pwd)}/android/tooot.jks",
        "android.injected.signing.store.password" => ENV["ANDROID_KEYSTORE_PASSWORD"],
        "android.injected.signing.key.alias" => ENV["ANDROID_KEYSTORE_ALIAS"],
        "android.injected.signing.key.password" => ENV["ANDROID_KEYSTORE_KEY_PASSWORD"],
      }
    )
    sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{File.expand_path('..', Dir.pwd)}/tooot-#{GITHUB_RELEASE}.apk"
  when "release"
    prepare_playstore_android
    build_android_app(
      task: 'clean bundle',
      build_type: 'release',
      project_dir: "./android",
      print_command: true,
      print_command_output: true,
      properties: {
        "expoSDK" => VERSIONS[:expo],
        "releaseChannel" => RELEASE_CHANNEL,
        "android.injected.signing.store.file" => "#{File.expand_path('..', Dir.pwd)}/android/tooot.jks",
        "android.injected.signing.store.password" => ENV["ANDROID_KEYSTORE_PASSWORD"],
        "android.injected.signing.key.alias" => ENV["ANDROID_KEYSTORE_ALIAS"],
        "android.injected.signing.key.password" => ENV["ANDROID_KEYSTORE_KEY_PASSWORD"],
      }
    )
    upload_to_play_store(
      track: "production",
      skip_upload_changelogs: true
    )
    build_android_app(
      task: 'assemble',
      build_type: 'release',
      project_dir: "./android",
      print_command: false,
      print_command_output: false,
      properties: {
        "expoSDK" => VERSIONS[:expo],
        "releaseChannel" => RELEASE_CHANNEL,
        "android.injected.signing.store.file" => "#{File.expand_path('..', Dir.pwd)}/android/tooot.jks",
        "android.injected.signing.store.password" => ENV["ANDROID_KEYSTORE_PASSWORD"],
        "android.injected.signing.key.alias" => ENV["ANDROID_KEYSTORE_ALIAS"],
        "android.injected.signing.key.password" => ENV["ANDROID_KEYSTORE_KEY_PASSWORD"],
      }
    )
    sh "mv #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]} #{File.expand_path('..', Dir.pwd)}/tooot-#{GITHUB_RELEASE}.apk"
  else
    if !is_ci
      build_android_app(
        task: 'assemble',
        build_type: 'release',
        project_dir: "./android"
      )
      adb(
        command: "install #{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}"
      )
    end
  end
end

lane :build do
  releaseExists = get_github_release(url: GITHUB_REPO, version: "v#{VERSION}", api_token: ENV['GH_PAT_GET_RELEASE'])
  if releaseExists
    puts("Release #{GITHUB_RELEASE} exists. Continue with building React Native only.")
  else
    puts("Release #{GITHUB_RELEASE} does not exist. Create new release as well as new native build.")
    cocoapods(clean_install: true, podfile: "./ios/Podfile")
    build_ios
    build_android
    case ENVIRONMENT
    when "candidate"
      github_release(prerelease: true)
    when "release"
      github_release(prerelease: false)
    end
  end
  expo_release
  rocket
end
