module RbSys::Mkmf

def base_makefile(cargo_dir)

def base_makefile(cargo_dir)
  base_makefile = dummy_makefile(__dir__).join("\n")
  base_makefile.gsub!("all install static install-so install-rb", "all static install-so install-rb")
  base_makefile.gsub!("clean-so::", "clean-so:\n\t-$(Q)$(RM) $(DLLIB)\n")
  base_makefile.gsub!(/^srcdir = .*$/, "srcdir = #{cargo_dir}")
  base_makefile
end

def cargo_command(cargo_dir, builder)

def cargo_command(cargo_dir, builder)
  builder.ext_dir = cargo_dir
  dest_path = File.join(Dir.pwd, "target")
  args = ARGV.dup
  args.shift if args.first == "--"
  cargo_cmd = builder.cargo_command(dest_path, args)
  Shellwords.join(cargo_cmd).gsub("\\=", "=").gsub(/\Acargo/, "$(CARGO)")
end

def create_rust_makefile(target, &blk)

Other tags:
    Example: Configure a custom build profile -
    Example: Basic -
def create_rust_makefile(target, &blk)
  if target.include?("/")
    target_prefix, target = File.split(target)
    target_prefix[0, 0] = "/"
  else
    target_prefix = ""
  end
  spec = Struct.new(:name, :metadata).new(target, {})
  builder = CargoBuilder.new(spec)
  yield builder if blk
  srcprefix = "$(srcdir)/#{builder.ext_dir}".chomp("/")
  RbConfig.expand(srcdir = srcprefix.dup)
  full_cargo_command = cargo_command(srcdir, builder)
  # rubocop:disable Style/GlobalVars
  make_install = +<<~MAKE
    RB_SYS_CARGO_PROFILE ?= #{builder.profile}
    RB_SYS_CARGO_FEATURES ?= #{builder.features.join(",")}
    CARGO ?= cargo
    ifeq ($(RB_SYS_CARGO_PROFILE),dev)
      RB_SYS_TARGET_DIR ?= debug
    else
      RB_SYS_TARGET_DIR ?= $(RB_SYS_CARGO_PROFILE)
    endif
    target_prefix = #{target_prefix}
    TARGET_NAME = #{target[/\A\w+/]}
    TARGET_ENTRY = #{RbConfig::CONFIG["EXPORT_PREFIX"]}Init_$(TARGET_NAME)
    CLEANLIBS = $(RUSTLIB) $(DLLIB) $(DEFFILE)
    DISTCLEANDIRS = target/
    RUBYARCHDIR   = $(sitearchdir)$(target_prefix)
    RUSTLIB = #{dllib_path(builder)}
    TARGET = #{target}
    DLLIB = $(TARGET).#{RbConfig::CONFIG["DLEXT"]}
    TARGET_DIR = #{Dir.pwd}/target/$(RB_SYS_TARGET_DIR)
    DEFFILE = $(TARGET_DIR)/$(TARGET)-$(arch).def
    #{base_makefile(srcdir)}
    #{env_vars(builder)}
    FORCE: ;
    $(TARGET_DIR):
    \t$(ECHO) creating target directory \\($(@)\\)
    \t$(Q) $(MAKEDIRS) $(TARGET_DIR)
    $(DEFFILE): $(TARGET_DIR)
    \t$(ECHO) generating $(@)
    \t$(Q) ($(COPY) $(srcdir)/$(TARGET).def $@ 2> /dev/null) || (echo EXPORTS && echo $(TARGET_ENTRY)) > $@
    $(DLLIB): $(DEFFILE) FORCE
    \t$(ECHO) generating $(@) \\("$(RB_SYS_CARGO_PROFILE)"\\)
    \t$(Q) #{full_cargo_command}
    \t$(Q) $(COPY) "$(RUSTLIB)" $@
    install: $(DLLIB) Makefile
    \t$(ECHO) installing $(DLLIB)
    \t$(Q) $(MAKEDIRS) $(RUBYARCHDIR)
    \t$(Q) $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
    all: #{$extout ? "install" : "$(DLLIB)"}
  MAKE
  gsub_cargo_command!(make_install, builder: builder)
  File.write("Makefile", make_install)
end

def dllib_path(builder)

def dllib_path(builder)
  builder.cargo_dylib_path(File.join(Dir.pwd, "target"))
end

def env_line(k, v)

def env_line(k, v)
  return unless v
  %($(DLLIB): export #{k} = #{v.gsub("\n", '\n')})
end

def env_or_makefile_config(key)

def env_or_makefile_config(key)
  ENV[key] || RbConfig::MAKEFILE_CONFIG[key]
end

def env_vars(builder)

def env_vars(builder)
  lines = builder.build_env.map { |k, v| env_line(k, v) }
  lines << env_line("CC", env_or_makefile_config("CC"))
  lines << env_line("AR", env_or_makefile_config("AR")) unless env_or_makefile_config("AR") == "libtool -static"
  lines.compact.join("\n")
end

def gsub_cargo_command!(cargo_command, builder:)

def gsub_cargo_command!(cargo_command, builder:)
  cargo_command.gsub!("--profile #{builder.profile}", "--profile $(RB_SYS_CARGO_PROFILE)")
  cargo_command.gsub!(%r{--features \S+}, "--features $(RB_SYS_CARGO_FEATURES)")
  cargo_command.gsub!(%r{/target/\w+/}, "/target/$(RB_SYS_TARGET_DIR)/")
  cargo_command
end