#!/usr/bin/env ruby

# Copyright (C) 2020 Igalia S. L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.

# Wrapper for a .cpp -> .o compilation command. It
# 1. converts the command to generate a `.s' file
# 2. runs the ASM postprocessor on it to generate the final `.s` file
# 3. assembles the `.s` file to a `.o` file

$asm_suffix_pre = ".pre.s"
$asm_suffix = ".s"
$postprocessor = "#{File.dirname($0)}/resolve-asm-file-conflicts.rb"


$intermediate_paths = []

# We need to work with indices a lot and unfortunately 'getoptlong' in
# the standard library doesn't expose optind, so we're going with
# array searches for simplicity.
def index_nofail(ary, f, errmsg)
  idx = ary.index { |el|
    f.call(el)
  }
  if idx.nil?
    $stderr.puts(errmsg)
    exit(3)
  end
  idx
end

# Find and return the source file for this compilation command,
# removing it from the args. Note that the path (A) as it appears here
# (coming from a cmake rule) is likely to be different to the
# anonymous argument (B) to the compilation command. However, A will
# be a suffix of B.
#
# Exit with an error if the argument is not there. This has already
# been checked by `cxx-wrapper`, otherwise we wouldn't be running.
def extract_input!(args)
  prefix = '-DPOSTPROCESS_ASM='

  idx = index_nofail(args, Proc.new { |arg|
    arg.start_with?(prefix)
  }, "No `-DPOSTPROCESS_ASM` argument`")

  path = args[idx][prefix.size..-1]
  if path.size == 0
    $stderr.puts("Empty path in -DPOSTPROCESS_ASM=")
    exit(3)
  end
  # We only need this to be defined for the preprocessor (not any
  # wrapper) from now on.
  args[idx] = "-DPOSTPROCESS_ASM"
  return path
end

# Get the index of the first argument ending in this suffix.
#
# Exit with an error if the argument isn't there. We're only ever
# called with arguments we know are being passed in by the build
# system.
def get_arg_idx_suffix(args, wanted)
  index_nofail(args, Proc.new { |arg|
                 arg.end_with?(wanted)
               }, "No argument ends with #{wanted}")
end

# Get index of a given argument. Die if it's not there.
def get_arg_idx(args, wanted)
  index_nofail(args, Proc.new { |arg|
                 arg == wanted
               }, "No `#{wanted}` argument")
end

# Get the index of `-o` and verify that an argument follows.
# Both are guaranteed to exist (from our build system).
def get_o_idx(args)
  i = get_arg_idx(args, '-o')
  if (i + 1) >= args.size
    $stderr.puts("No argument to `-o`")
    exit(3)
  end
  i
end

# Run command and die if it fails, propagating the exit code.
def run_cmd(cmd)
  pid = Process.spawn(*cmd)
  Process.waitpid(pid)
  ret = $?
  if not ret.success?
    $stderr.puts("Error running cmd: #{ret}")
    exit(ret.exitstatus)
  end
end

# Convert
#    cxx -o blah.o -c blah.cpp
# to
#    cxx -o blah.s -S blah.cpp
def build_cxx_cmd(args)
  c_idx = get_arg_idx(args, '-c')
  o_idx = get_o_idx(args)

  cxx_args = args.clone

  cxx_args[c_idx] = '-S'
  o_path = cxx_args[o_idx + 1]
  cxx_args[o_idx + 1] = o_path.sub(/[.]o$/, $asm_suffix)
  $intermediate_paths << cxx_args[o_idx + 1]
  if cxx_args[o_idx + 1] == o_path
    $stderr.puts("Output file name not an object file: `#{o_path}`")
    exit(3)
  end
  cxx_args
end

# Do
#     mv blah.S blah.pre.S
# The reason we do a rename instead of directly generating the .pre.s
# file when compiling is so that the corresponding .dwo file will have
# the correct name embedded.
def rename_s_file(args)
  o_path = args[get_o_idx(args) + 1]
  File.rename(o_path.sub(/[.]o$/, $asm_suffix),
              o_path.sub(/[.]o$/, $asm_suffix_pre))
end

# Build
#     postprocessor blah.pre.S blah.S
def build_postprocessor_cmd(args)
  o_path = args[get_o_idx(args) + 1]

  pp_args = [
    $postprocessor,
    o_path.sub(/[.]o$/, $asm_suffix_pre), # input
    o_path.sub(/[.]o$/, $asm_suffix) # output
  ]
  $intermediate_paths << pp_args[-2]
  $intermediate_paths << pp_args[-1]
  pp_args
end

# Build
#     cxx -o blah.o -c blah.S
def build_as_cmd(args, i_path)
  i_idx = get_arg_idx_suffix(args, i_path)
  o_path = args[get_o_idx(args) + 1]

  as_args = args.clone
  i_path = as_args[i_idx]
  as_args[i_idx] = o_path.sub(/[.]o$/, $asm_suffix)
  as_args
end

args = ARGV.to_a
i_path = extract_input!(args)

begin
  run_cmd(build_cxx_cmd(args))
  rename_s_file(args)
  run_cmd(build_postprocessor_cmd(args))
  run_cmd(build_as_cmd(args, i_path))
ensure
  $intermediate_paths.each { |p|
    if File.exist?(p)
      File.delete(p)
    end
  }
end
