#!/usr/bin/env ruby
# frozen_string_literal: true

# Copyright (c) 2017 - 2020 Minqi Pan et al.
#
# This file is part of Ruby Packer, distributed under the MIT License
# For full terms see the included LICENSE file

require 'rubygems'
require 'bundler/setup'
Bundler.require(:default)

require_relative '../lib/compiler'
require 'optparse'

USAGE = %{

Ruby Packer (rubyc) v#{::Compiler::VERSION}
Compiling your Ruby application into a single executable.

Usage
  rubyc [OPTION]... [ENTRANCE_FILE]
  ENTRANCE_FILE refers to the path of an executable ruby script from your project, e.g. "bin/rails".
  If ENTRANCE_FILE was not provided, a single raw Ruby interpreter executable would be produced.
}.strip

EXAMPLES = %{

Examples

  Producing a single Ruby interpreter executable:
    rubyc
    ./a.out (or a.exe on Windows)

  Compiling a CLI tool:
    git clone --depth 1 https://github.com/pmq20/ruby-packer.git
    cd ruby-packer
    rubyc bin/rubyc
    ./a.out (or a.exe on Windows)

  Compiling a Rails application:
    rails new yours
    cd yours
    rubyc bin/rails
    ./a.out server (or a.exe server on Windows)
}.strip

options = {}

outer_opts = nil

usage = lambda do |out|
  out.puts outer_opts
end

OptionParser.new do |opts|
  opts.banner = USAGE

  opts.on('-rDIR', '--root=DIR', 'The path to the root of your application') do |dir|
    options[:root] = dir
  end

  opts.on('-oFILE', '--output=FILE', 'The path of the output file') do |file|
    options[:output] = file
  end

  opts.on('-dDIR', '--tmpdir=DIR', 'The directory for temporary files') do |dir|
    options[:tmpdir] = dir
  end

  opts.on('--keep-tmpdir', 'Keeps all temporary files that were generated last time') do
    options[:keep_tmpdir] = true
  end

  opts.on('--openssl-dir=DIR', 'The path to openssl') do |dir|
    options[:openssl_dir] = dir
  end

  opts.on('--make-args=ARGS', 'Extra arguments to be passed to make') do |args|
    options[:make_args] = args
  end

  opts.on('--nmake-args=ARGS', 'Extra arguments to be passed to nmake') do |args|
    options[:nmake_args] = args
  end

  opts.on('-i', '--ignore-file=STRING', 'Ignore file(s) from build') do |string|
    if options[:ignore_file].is_a?(Array)
      options[:ignore_file] << string
    else
      options[:ignore_file] = [string]
    end
  end

  opts.on('--debug', 'Enable debug mode') do
    options[:debug] = true
  end

  opts.on('--quiet', 'Enable quiet mode') do
    options[:quiet] = true
  end

  opts.on('-v', '--version', 'Prints the version of rubyc and exit') do
    puts ::Compiler::VERSION
    exit 0
  end

  opts.on('-V', '--ruby-version', 'Prints the version of the Ruby runtime and exit') do
    puts ::Compiler.ruby_version
    exit 0
  end

  opts.on('--ruby-api-version', 'Prints the version of the Ruby API and exit') do
    puts ::Compiler.ruby_api_version
    exit 0
  end

  opts.on('-h', '--help', 'Prints this help and exit') do
    usage.call($stdout)
    $stdout.puts
    $stdout.puts EXAMPLES
    exit 0
  end

  outer_opts = opts
end.parse!

entrance = ARGV[-1]

begin
  instance = ::Compiler.new entrance, options
  instance.run!
rescue ::Compiler::Error => e
  warn e.message
  exit 1
end
