require 'json'
require 'yaml'

def base_package_name
  return sh("grep \"applicationId \" ../app/build.gradle | awk '{print $2}' | tr -d \"'\\\"\"", log:false).strip
end

def package_name(flavor = "")
  return (flavor == "" || flavor == "standard" || flavor == "googleSucks") ? base_package_name : base_package_name + "." + flavor
end

def version_name
  return sh("grep \"versionName\" ../app/build.gradle | awk '{print $2}' | tr -d \"'\\\"\"").strip
end

def version_code
  return sh("grep \"versionCode\" ../app/build.gradle | awk '{print $2}' | tr -d \"'\\\"\"").strip
end

def last_tag
  return sh("git describe --abbrev=0").strip
end

before_all do |lane, options|
  if !lane.to_s.start_with?('update_metadata')
    if options[:check_version] != false
      puts("Checking that latest commit is tagged like I like it. If you want to disable this, run with 'fastlane [lane] check_version:no'")
      check_version # This exits if something goes wrong
    end
    prompt_password_once
    gradle(task: "clean")
    # gradle(task: "spotlessCheck")
  end
end

def check_version
  ensure_git_status_clean

  changelog = "metadata/android/en-US/changelogs/#{version_code}.txt"
  if !File.file?(changelog)
    UI.user_error!("#{changelog} file doesn't exist")
  end

  last_commit_hash = last_git_commit[:commit_hash]
  last_tag_hash = sh("git rev-parse #{last_tag}^{}", log:false).strip

  if last_commit_hash != last_tag_hash
    UI.user_error!("Last commit not tagged with version (last git tag: #{last_tag}). Aborting.")
  end

  if "v#{version_name}" != last_tag
    UI.user_error!("Tag (#{last_tag}) and versionName in build-gradle (#{version_name}) differ. Aborting.")
  end

  if !last_tag.match(/v[0-9]\.[0-9](\.[0-9])?/)
    UI.user_error!("Tag doesn't match \"vX.Y.Z\" format")
  end
end

password = ""
private_lane :prompt_password_once do
  if password == ""
    password = prompt(
      text: "Please enter keystore password:",
      secure_text: true
    )
  end
end

private_lane :build_flavor do |values|
  flavor = values[:flavor]
  prompt_password_once
  gradle(
    task: "assemble",
    build_type: "Release",
    flavor: flavor,
    print_command: false,
    properties: {
      "android.injected.signing.store.file" => "/keys/apk-release/juanitobananas-release-key.jks",
      "android.injected.signing.store.password" => password,
      "android.injected.signing.key.alias" => "app",
      "android.injected.signing.key.password" => password,
    }
  )
end

private_lane :bundle_flavor do |values|
  flavor = values[:flavor]
  prompt_password_once
  gradle(
    task: "bundle",
    build_type: "Release",
    flavor: flavor,
    print_command: false,
    properties: {
      "android.injected.signing.store.file" => "/keys/apk-release/juanitobananas-upload-keystore-for-bundles.jks",
      "android.injected.signing.store.password" => password,
      "android.injected.signing.key.alias" => "upload",
      "android.injected.signing.key.password" => password,
    }
  )
end

private_lane :deploy_flavor do |values|
  flavor = values[:flavor]
  build_flavor(flavor: flavor)
  upload_to_play_store(
    track: "production",
    package_name: package_name(flavor),
    metadata_path: "fastlane/#{flavor}/metadata/android",
    skip_upload_images: true,
    skip_upload_screenshots: true
  )
  gradle(task: "clean")
end

private_lane :deploy_bundle_flavor do |values|
  flavor = values[:flavor]
  bundle_flavor(flavor: flavor)
  upload_to_play_store(
    track: "production",
    package_name: package_name(flavor),
    metadata_path: "fastlane/#{flavor}/metadata/android",
    skip_upload_images: true,
    skip_upload_screenshots: true
  )
  gradle(task: "clean")
end

private_lane :update_metadata_flavor do |values|
  flavor = values[:flavor]
  upload_to_play_store(
    track: "production",
    package_name: package_name(flavor),
    metadata_path: "fastlane/" + flavor + "/metadata/android",
    skip_upload_apk: true
  )
end

private_lane :fetch_metadata_flavor do |values|
  flavor = values[:flavor]
  package_name = flavor == "standard" ? base_package_name : base_package_name + "." + flavor
  sh("fastlane supply init --metadata_path ./#{flavor}/metadata/android --package_name #{package_name}")
end

private_lane :build_standard do
  standard_grep = sh("grep \"standard\" ../app/build.gradle || true").strip
  if (standard_grep == "")
    puts("Didn't find standard flavor. Not using flavor at all")
    build_flavor
  else
    puts("Building 'standard' flavor")
    build_flavor(flavor: "standard")
  end
end

private_lane :gitlab_release_for_project_id do |values|# only release standard release for now
  gitlab_project_id = values[:project_id]

  if values[:check_version] != false
    puts("Checking that latest commit is tagged like I like it. If you want to disable this, run with 'fastlane gitlab_release check_version:no'")
    check_version # This exits if something goes wrong
  end

  puts("Releasing tag: #{last_tag}")

  build_standard

  gitlab_config = YAML::load_file('/keys/gitlab-api-token')
  gitlab_auth_token = gitlab_config["gitlab_auth_token"]

  upload_result_json = sh("curl \
      --silent \
      --header 'PRIVATE-TOKEN: #{gitlab_auth_token}' \
      --form 'file=@#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}' \
      --request POST https://gitlab.com/api/v4/projects/#{gitlab_project_id}/uploads", log:false)

  upload_result = JSON.parse(upload_result_json)
  markdown_upload_link = upload_result["markdown"]

  tag_name = last_tag
  release_name = "Version #{version_name} (#{version_code})"
  description = "Download #{markdown_upload_link}\n\nChangelog [#{version_code}.txt](fastlane/metadata/android/en-US/changelogs/#{version_code}.txt)"
  data = {
      name: release_name,
      tag_name: tag_name,
      description: description
  }.to_json

  release_result_json = sh("curl \
          --silent \
          --header 'Content-Type: application/json' \
          --header 'PRIVATE-TOKEN: #{gitlab_auth_token}' \
          --data '#{data}' \
          --request POST https://gitlab.com/api/v4/projects/#{gitlab_project_id}/releases", log:false)

  release_result = JSON.parse(release_result_json)
  if !release_result.has_key? 'tag_name'
    UI.user_error!("Failed to create release: #{release_result}")
  end
end
