require 'package'
# build order: harfbuzz => freetype => fontconfig => pango

class Harfbuzz < Package
  description 'HarfBuzz is an OpenType text shaping engine.'
  homepage 'https://www.freedesktop.org/wiki/Software/HarfBuzz/'
  @_ver = '7.1.0'
  version @_ver
  license 'Old-MIT, ISC and icu'
  compatibility 'all'
  source_url 'https://github.com/harfbuzz/harfbuzz.git'
  git_hashtag @_ver

  binary_url({
    aarch64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/harfbuzz/7.1.0_armv7l/harfbuzz-7.1.0-chromeos-armv7l.tar.zst',
     armv7l: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/harfbuzz/7.1.0_armv7l/harfbuzz-7.1.0-chromeos-armv7l.tar.zst',
       i686: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/harfbuzz/7.1.0_i686/harfbuzz-7.1.0-chromeos-i686.tar.zst',
     x86_64: 'https://gitlab.com/api/v4/projects/26210301/packages/generic/harfbuzz/7.1.0_x86_64/harfbuzz-7.1.0-chromeos-x86_64.tar.zst'
  })
  binary_sha256({
    aarch64: '4f7a52a90c3ba072e520ce35d1f3ae98d5673394703ef2af3bc11ecc59be653e',
     armv7l: '4f7a52a90c3ba072e520ce35d1f3ae98d5673394703ef2af3bc11ecc59be653e',
       i686: '51ff026b275866174cf2e3b3b86f5351c542ae6bd62763124eba9ea69d8f8471',
     x86_64: '6403cc02542560d51c9e64ab8ab502774a8324f59f8e936956dc3425565c67b5'
  })

  depends_on 'brotli' # R
  depends_on 'bz2' # R
  depends_on 'chafa' # R
  depends_on 'expat' # R
  # depends_on 'fontconfig' # This pulls in freetype.
  # depends_on 'freetype' # R harfbuzz provides this.
  depends_on 'gcc' # R
  depends_on 'glibc' # R
  depends_on 'glib' # R
  depends_on 'gobject_introspection' => :build
  depends_on 'graphite' # R
  depends_on 'icu4c' # R
  depends_on 'libffi' => :build
  depends_on 'libpng' # R
  depends_on 'libx11' # R
  depends_on 'libxcb' # R
  depends_on 'libxext' # R
  depends_on 'libxrender' # R
  depends_on 'lzo' # R
  depends_on 'pcre' => :build
  depends_on 'pixman' # R Needed for cairo subproject.
  depends_on 'zlibpkg' # R

  # provides freetype (sans harfbuzz), ragel, and a non-x11 cairo stub

  no_env_options
  conflicts_ok

  def self.prebuild
    %w[fontconfig freetype].each do |build_exclusion|
      next unless File.exist? "#{CREW_PREFIX}/etc/crew/meta/#{build_exclusion}.filelist"

      puts "#{build_exclusion} needs to be uninstalled before this build.".lightred
    end
  end

  def self.build
    system 'update-ca-certificates --fresh'
    system "meson setup #{CREW_MESON_OPTIONS} \
      --wrap-mode=default \
      --default-library=both \
      -Dbenchmark=disabled \
      -Dcairo=enabled \
      -Ddocs=disabled \
      -Dfreetype=enabled \
      -Dgraphite2=enabled \
      -Dintrospection=enabled \
      -Dragel_subproject=true \
      -Dtests=disabled \
      builddir"
    system 'meson configure builddir'
    system "mold -run #{CREW_NINJA} -C builddir"
  end

  def self.install
    system "DESTDIR=#{CREW_DEST_DIR} #{CREW_NINJA} -C builddir install"
    # The following are included the libpng package.
    FileUtils.rm Dir["#{CREW_DEST_LIB_PREFIX}/libpng*"]
    FileUtils.rm Dir["#{CREW_DEST_PREFIX}/include/libpng16/png*"]
    FileUtils.rm Dir["#{CREW_DEST_LIB_PREFIX}/pkgconfig/libpng*"]
    # Create libtool file. Needed by handbrake build
    return if File.file?("#{CREW_DEST_LIB_PREFIX}/#{@libname}.la")

    @libname = name.to_s.start_with?('lib') ? name.downcase : "lib#{name.downcase}"
    @libnames = Dir["#{CREW_DEST_LIB_PREFIX}/#{@libname}.so*"]
    @libnames = Dir["#{CREW_DEST_LIB_PREFIX}/#{@libname}-*.so*"] if @libnames.empty?
    @libnames.each do |s|
      s.gsub!("#{CREW_DEST_LIB_PREFIX}/", '')
    end
    @dlname = @libnames.grep(/.so./).first
    @libname = @dlname.gsub(/.so.\d+/, '')
    @longest_libname = @libnames.max_by(&:length)
    @libvars = @longest_libname.rpartition('.so.')[2].split('.')

    @libtool_file = <<~LIBTOOLEOF
      # #{@libname}.la - a libtool library file
      # Generated by libtool (GNU libtool) (Created by Chromebrew)
      #
      # Please DO NOT delete this file!
      # It is necessary for linking the library.

      # The name that we can dlopen(3).
      dlname='#{@dlname}'

      # Names of this library.
      library_names='#{@libnames.reverse.join(' ')}'

      # The name of the static archive.
      old_library='#{@libname}.a'

      # Linker flags that cannot go in dependency_libs.
      inherited_linker_flags=''

      # Libraries that this one depends upon.
      dependency_libs=''

      # Names of additional weak libraries provided by this library
      weak_library_names=''

      # Version information for #{name}.
      current=#{@libvars[0]}
      age=#{@libvars[1]}
      revision=#{@libvars[2]}

      # Is this an already installed library?
      installed=yes

      # Should we warn about portability when linking against -modules?
      shouldnotlink=no

      # Files to dlopen/dlpreopen
      dlopen=''
      dlpreopen=''

      # Directory that this library needs to be installed in:
      libdir='#{CREW_LIB_PREFIX}'
    LIBTOOLEOF
    File.write("#{CREW_DEST_LIB_PREFIX}/#{@libname}.la", @libtool_file)
  end

  def self.preinstall
    @device = JSON.parse(File.read("#{CREW_CONFIG_PATH}device.json"), symbolize_names: true)
    return unless @device[:installed_packages].any? { |elem| elem[:name] == 'freetype' }

    system "sed -i '/freetype2/d;/libfreetype/d' filelist"
    system "sed -i '/freetype2/d;/libfreetype/d' dlist"
  end

  def self.postinstall
    # This should become a function.
    # check for conflicts with other installed files
    @override_allowed = %w[fontconfig cairo]
    puts 'Checking for conflicts with files from installed packages...'
    conflicts = []
    conflictscmd = `grep --exclude #{CREW_META_PATH}#{name}.filelist -Fxf #{CREW_META_PATH}#{name}.filelist #{CREW_META_PATH}*.filelist`
    conflicts << conflictscmd.gsub(/(\.filelist|#{CREW_META_PATH})/, '').split("\n")
    conflicts.reject!(&:empty?)
    return if conflicts.empty?

    if conflicts_ok?
      puts 'Warning: There is a conflict with the same file in another package.'.orange
    else
      puts 'Error: There is a conflict with the same file in another package.'.lightred
      @_errors = 1
    end
    conflicts.each do |conflict|
      conflict.each do |thisconflict|
        singleconflict = thisconflict.split(':', -1)
        system "sed -i '\\?^#{singleconflict[1]}?d'  #{CREW_META_PATH}/#{singleconflict[0]}.filelist" if @override_allowed.include?(singleconflict[0])
      end
    end
  end
end
