# Copyright 2022-2024 Frederico de Oliveira Linhares
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'rake/clean'
require 'rake/loaders/makefile'

if RUBY_PLATFORM.include? 'cygwin' then
  load './rake/windows.rake'
  OS = :windows
else
  load './rake/linux.rake'
  OS = :linux
end

OBJ = 'candy_gear'

VERSION = '0.1.0'

MRUBY_VERSION = '3.3.0'
MRUBY_ZIP_FILE = "mruby-#{MRUBY_VERSION}.zip"
MRUBY_STATIC_LIB = "mruby-#{MRUBY_VERSION}/build/host/lib/libmruby.a"

DATA_DIR = '/usr/local/share/candy_gear'

CPP_H_FILES = FileList[
  'src/**/*.hpp'
]
CPP_FILES = FileList[
  'src/**/*.cpp'
]
CPP_OBJS = CPP_FILES.ext('.o')

RB_LIBS = FileList[
  'lib/**/*.rb'
]

GLSL_FILES = FileList[
  'glsl/*.glsl'
]

SPV_FILES = GLSL_FILES.ext('.spv')

LIBRARIES = [
  'SDL2',
  'SDL2_mixer',
  'freetype',
  'm'
] + OS_LIBRARIES

PKG_CONFIG = [
  'freetype2'
]

pkg_arguments = PKG_CONFIG.inject('') {_1 + "#{_2} "}
PKG_VALUES = %x[pkg-config --cflags #{pkg_arguments}]

CLEAN.include(
  FileList[
    'src/**/*.o',
    'glsl/*.spv'
  ]
)

file MRUBY_ZIP_FILE do
  system("wget https://github.com/mruby/mruby/archive/#{MRUBY_VERSION}.zip "\
         "-O #{MRUBY_ZIP_FILE}")
end

directory "mruby-#{MRUBY_VERSION}"
file "mruby-#{MRUBY_VERSION}" => MRUBY_ZIP_FILE do
  `unzip #{MRUBY_ZIP_FILE}`
end

# Candy Gear aims to be portable to several platforms. The language is embedded
# inside the engine to ensure all versions of the engine have precisely the
# same features.
file MRUBY_STATIC_LIB => ["mruby-#{MRUBY_VERSION}"] do
  Dir.chdir("mruby-#{MRUBY_VERSION}") do
    ENV['MRUBY_CONFIG'] = '../ruby_build_config.rb'
    `rake`
  end
end

task :doc do
  `doxygen Doxyfile`
end

rule '.o' => ['.cpp', "mruby-#{MRUBY_VERSION}"] do |t|
  system("g++ #{t.source} -o #{t.name} -g -D DEBUG=1 -c -std=c++23 "\
         "-Imruby-#{MRUBY_VERSION}/include/ #{PKG_VALUES}")
end

task :pkg do
  name = "#{OBJ}-#{VERSION}"
  files =
    FileList[
      'CODE_OF_CONDUCT.markdown',
      'Doxyfile',
      'LICENSE.txt',
      'Rakefile',
      'README.markdown'
    ] +
    CPP_H_FILES +
    CPP_FILES +
    RB_LIBS

  `mkdir -p pkg`
  `tar -czvf pkg/#{name}.tar.gz --transform 's,^,#{name}/,' #{files}`
end

rule '.spv' => ['.glsl'] do |t|
  system("glslangValidator -V #{t.source} -o #{t.name}")
end

task :lib do
  destdir = ENV['DESTDIR'] || ''

  `install -d #{destdir}#{DATA_DIR}/lib`
  RB_LIBS.each do |path|
    subdir = /(\/[[:alnum:]]+)\//.match(path)&.captures&.at(0)
    `install -d #{destdir}#{DATA_DIR}/lib#{subdir}` unless subdir.nil?
    `install #{path} #{destdir}#{DATA_DIR}/lib#{subdir}`
  end
end

task build: CPP_OBJS + SPV_FILES + [MRUBY_STATIC_LIB] do
  libs = LIBRARIES.inject('') {_1 + "-l#{_2} "}

  flags = ''
  case OS
  when :windows
    flags = '-w -Wl,-subsystem,windows'
  when :linux
  end

  system("g++ -o #{OBJ} #{CPP_OBJS} #{MRUBY_STATIC_LIB} #{flags} #{libs}")
end

task default: %[build]