# frozen_string_literal: true

require File.expand_path("../../lib/rdkafka/version", __FILE__)
require "digest"
require "fileutils"
require "open-uri"

task default: :clean do
  # For nix users, nix can't locate the file paths because the packages it's requiring aren't managed by the system but are
  # managed by nix itself, so using the normal file paths doesn't work for nix users.
  #
  # Mini_portile causes an issue because it's dependencies are downloaded on the fly and therefore don't exist/aren't
  # accessible in the nix environment
  if ENV.fetch("RDKAFKA_EXT_PATH", "").empty?
    # Download and compile librdkafka if RDKAFKA_EXT_PATH is not set
    require "mini_portile2"
    recipe = MiniPortile.new("librdkafka", Rdkafka::LIBRDKAFKA_VERSION)

    # Use default homebrew openssl if we're on mac and the directory exists, is not using nix-prepared libraries
    # and each of flags is not already set
    if recipe.host&.include?("darwin") && system("which brew &> /dev/null") && Dir.exist?((homebrew_prefix = `brew --prefix openssl`.strip).to_s) && !ENV.key?("NIX_LDFLAGS")
      ENV["CPPFLAGS"] = "-I#{homebrew_prefix}/include" unless ENV.key?("CPPFLAGS")
      ENV["LDFLAGS"] = "-L#{homebrew_prefix}/lib" unless ENV.key?("LDFLAGS")
    end

    releases = File.expand_path(File.join(File.dirname(__FILE__), "../dist"))

    recipe.files << {
      url: "file://#{releases}/librdkafka-#{Rdkafka::LIBRDKAFKA_VERSION}.tar.gz",
      sha256: Rdkafka::LIBRDKAFKA_SOURCE_SHA256
    }
    recipe.configure_options = ["--host=#{recipe.host}"]

    recipe.patch_files = Dir[File.join(releases, "patches", "*.patch")].sort

    # Disable using libc regex engine in favor of the embedded one
    # The default regex engine of librdkafka does not always work exactly as most of the users
    # would expect, hence this flag allows for changing it to the other one
    if ENV.key?("RDKAFKA_DISABLE_REGEX_EXT")
      recipe.configure_options << "--disable-regex-ext"
    end

    recipe.cook
    # Move dynamic library we're interested in
    if recipe.host.include?("darwin")
      from_extension = "1.dylib"
      to_extension = "dylib"
    else
      from_extension = "so.1"
      to_extension = "so"
    end
    lib_path = File.join(File.dirname(__FILE__), "ports/#{recipe.host}/librdkafka/#{Rdkafka::LIBRDKAFKA_VERSION}/lib/librdkafka.#{from_extension}")
    FileUtils.mv(lib_path, File.join(File.dirname(__FILE__), "librdkafka.#{to_extension}"))
    # Cleanup files created by miniportile we don't need in the gem
    FileUtils.rm_rf File.join(File.dirname(__FILE__), "tmp")
    FileUtils.rm_rf File.join(File.dirname(__FILE__), "ports")
  else
    # Otherwise, copy existing libraries to ./ext
    if ENV["RDKAFKA_EXT_PATH"].nil? || ENV["RDKAFKA_EXT_PATH"].empty?
      raise "RDKAFKA_EXT_PATH must be set in your nix config when running under nix"
    end
    files = [
      File.join(ENV["RDKAFKA_EXT_PATH"], "lib", "librdkafka.dylib"),
      File.join(ENV["RDKAFKA_EXT_PATH"], "lib", "librdkafka.so")
    ]
    files.each { |ext| FileUtils.cp(ext, File.dirname(__FILE__)) if File.exist?(ext) }
  end
end

task :clean do
  FileUtils.rm_f File.join(File.dirname(__FILE__), "librdkafka.dylib")
  FileUtils.rm_f File.join(File.dirname(__FILE__), "librdkafka.so")
  FileUtils.rm_rf File.join(File.dirname(__FILE__), "ports")
  FileUtils.rm_rf File.join(File.dirname(__FILE__), "tmp")
end

namespace :dist do
  task :dir do
    ENV["RDKAFKA_DIST_PATH"] ||= File.expand_path(File.join(File.dirname(__FILE__), "..", "dist"))
  end

  task file: "dist:dir" do
    ENV["RDKAFKA_DIST_FILE"] ||= File.join(ENV["RDKAFKA_DIST_PATH"], "librdkafka_#{Rdkafka::LIBRDKAFKA_VERSION}.tar.gz")
  end

  task clean: "dist:file" do
    Dir.glob(File.join(ENV["RDKAFKA_DIST_PATH"].to_s, "*")).each do |filename|
      next if filename.include? ENV["RDKAFKA_DIST_FILE"]

      FileUtils.rm_rf filename
    end
  end

  task download: "dist:file" do
    version = Rdkafka::LIBRDKAFKA_VERSION
    librdkafka_download = "https://codeload.github.com/confluentinc/librdkafka/tar.gz/v#{version}"

    URI.open(librdkafka_download) do |file|
      filename = ENV["RDKAFKA_DIST_FILE"]
      data = file.read

      if Digest::SHA256.hexdigest(data) != Rdkafka::LIBRDKAFKA_SOURCE_SHA256
        raise "SHA256 does not match downloaded file"
      end

      File.write(filename, data)
    end
  end

  task update: %w[dist:download dist:clean]
end

namespace :build do
  desc "Build librdkafka at the given git sha or tag"
  task :git, [:ref] do |task, args|
    ref = args[:ref]
    version = "git-#{ref}"

    recipe = MiniPortile.new("librdkafka", version)
    recipe.files << "https://github.com/confluentinc/librdkafka/archive/#{ref}.tar.gz"
    recipe.configure_options = ["--host=#{recipe.host}", "--enable-static", "--enable-zstd"]
    recipe.patch_files = Dir[File.join(releases, "patches", "*.patch")].sort
    recipe.cook

    ext = recipe.host.include?("darwin") ? "dylib" : "so"
    lib = File.expand_path("ports/#{recipe.host}/librdkafka/#{version}/lib/librdkafka.#{ext}", __dir__)

    # Copy will copy the content, following any symlinks
    FileUtils.cp(lib, __dir__)
  end
end
