class Bornagain < Formula
  require 'etc'

  desc "Open-source research software to simulate and fit "\
       "neutron and x-ray reflectometry and grazing-incidence small-angle scattering"
  homepage "https://bornagainproject.org"

  url "https://jugit.fz-juelich.de/mlz/bornagain.git", branch: "a.addHomebrewRecipe", depth: 1, using: :git

  version "22.0"
  license "GNU GPL"

  depends_on "cmake" => "3.20"
  depends_on "fftw"
  depends_on "gsl"
  depends_on "boost"
  depends_on "libtiff"
  depends_on "qt@6"
  depends_on "libcerf"
  depends_on "libformfactor"
  depends_on "python@3"

  resource "numpy" do
    url "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz"
    sha256 "2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"
  end

  def build_dir
    "#{buildpath}/build/"
  end

  def local_dir
      "#{build_dir}/var/local/"
  end

  def nproc
    [Etc.nprocessors - 2, 1].max
  end

  def python3_exe
    "python3"
  end

  def qt_cmake_dir
    "#{Formula["qt@6"].prefix}/lib/cmake/"
  end

  def ff_cmake_dir
    Formula["libformfactor"].prefix/"cmake/"
  end

  def cmake_exe
    "#{Formula["cmake"].opt_bin.realpath}/cmake"
  end

  def install

    if not OS.mac?
      puts ".: Warning: This BornAgain install script is intended for MacOS only."
    end

    if Hardware::CPU.arm?
      puts ".: ARM architecture detected."
    elsif Hardware::CPU.intel?
      puts ".: Intel architecture detected."
    else
      odie ".: Hardware architecture is not supported."
    end

    if Hardware::CPU.is_64_bit?
      puts ".: 64-bit architecture detected."
    else
      odie ".: Hardware architecture is not supported."
    end

    cmake = Formula["cmake"]
    cmake_dir = cmake.prefix.realpath
    cmake_ver = cmake.version
    # path of the Python executable
    py_dir = `#{python3_exe} -c "import sys; print(sys.executable)"`.strip
    # major and minor version of the Python platform
    py_ver = `#{python3_exe} --version`.split[1]
    py_v = py_ver.split('.')
    py_v_major, py_v_minor = py_v[0].to_i, py_v[1].to_i

    puts ".: CMake #{cmake_ver} at '#{cmake_dir}'"
    puts ".: Python #{py_ver} at '#{py_dir}'"
    puts ".: BornAgain #{version} build directory: '#{build_dir}'"
    puts ".: BornAgain installation prefix: '#{prefix}'"
    puts ".: std_cmake_args = ", std_cmake_args.inspect

    if py_v_major < 3 or py_v_minor < 8
      odie ".: BornAgain requires Python 3.8 or newer."
    end

    # Python virtual environment
    venv_root = "#{local_dir}/venv"
    venv_py = "#{venv_root}/bin/python3"

    py_pkgs = ["numpy"]

    puts ".: Creating Python virtualenv in '#{venv_root}'..."
    system python3_exe, "-m", "venv", "--clear", "#{venv_root}"

    py_pkg_info = {}
    name_rx = /Name\s*:\s*([\w_]+)/  # eg. 'Name: numpy'
    version_rx = /Version\s*:\s*([\d.]+)/  # eg., 'Version: 1.2.3'
    py_pkgs.each do |pkg|
      puts "   - Installing #{pkg} in the Python virtualenv..."

      resource(pkg).stage do
        system venv_py, "-m", "pip", "install", "."
      end

      # extract package info via `pip show`
      info = `#{venv_py} -m pip show #{pkg}`
      nm = info.match(name_rx)[1]
      ver = info.match(version_rx)[1]
      py_pkg_info[nm] = ver
    end

    puts ".: Python virtualenv:"
    py_pkg_info.each do |nm, ver|
      puts "   #{nm} : #{ver}"
    end

    puts ".: Building BornAgain..."

    ba_cmd = [cmake_exe, "-S", "#{buildpath}", "-B", "#{build_dir}",
              *std_cmake_args, "-DBA_APPLE_HOMEBREW=ON",
              "-DBA_TESTS=OFF", "-DBA_PY_PACK=OFF",
              "-DBORNAGAIN_PYTHON=ON",
              "-DCMAKE_PREFIX_PATH=#{ff_cmake_dir};#{qt_cmake_dir}",
              "-DPython3_EXECUTABLE=#{venv_py}"]

    puts ">> " + ba_cmd.join(" ")

    # CMake configuration step
    system *ba_cmd

    # CMake build step
    system cmake_exe, "--build", "#{build_dir}",
           "--config", "Release", "--parallel", nproc

    puts ".: Building BornAgain: Done."

    system cmake_exe, "--install", "#{build_dir}", "--config", "Release"
  end

  def post_install
    # create symlinks
    brew_bin_pth = (Pathname "#{HOMEBREW_PREFIX}/bin/").realpath

    # main executable
    brew_bin_pth.install_symlink "#{prefix}/bin/bornagain" => "bornagain"
  end

end
