module SvelteOnRails::Installer::Npm

def self.check_version(current_version, minimal_version)

def self.check_version(current_version, minimal_version)
  if !current_version
    return false
  elsif !minimal_version.present?
    return true
  else
    compare_version_arrays(current_version, minimal_version)
  end
end

def self.compare_version_arrays(current_version, minimal_version)

def self.compare_version_arrays(current_version, minimal_version)
  raise "ERROR: current_version must be an array" unless current_version.is_a?(Array)
  raise "ERROR: minimal_version must be an array" unless current_version.is_a?(Array)
  current_version.each_with_index do |v, i|
    raise "ERROR: current_version entries must be an integer" unless v.is_a?(Integer)
    if minimal_version[i]
      raise "ERROR: minimal_version entries must be an integer" unless minimal_version[i].is_a?(Integer)
      if v < minimal_version[i]
        return false
      end
    end
  end
  true
end

def self.inspect_package(package_name)

def self.inspect_package(package_name)
  pkg = nil
  version = nil
  if File.exist?('package-lock.json')
    pl = JSON.parse(File.read('package-lock.json'))
    unless pl['packages']
      raise "ERROR: package-lock.json found, but no packages found, seems to be corrupted."
    end
    pkg = pl['packages'].keys.grep(/\/#{package_name}$/).first
    version = pl['packages'][pkg]['version'] if pkg
  end
  if pkg
    {
      type: pkg.match(/^.*?(?=\/[^\/]*$)/).to_s,
      version: version.split('.').map(&:to_i)
    }
  end
end

def self.install_or_update_package(package_name, minimal_version: nil, update_to_latest: true)

def self.install_or_update_package(package_name, minimal_version: nil, update_to_latest: true)
  pkg = inspect_package(package_name)
  to_do = !check_version((pkg ? pkg[:version] : nil), minimal_version)
  if to_do
    cmd = if update_to_latest
            "npm install #{package_name}@latest"
          else
            raise "ERROR: not implemented"
          end
    stdout, stderr, status = Open3.capture3(cmd)
    if stderr.present?
      raise "ERROR #{cmd} => #{stderr}"
    end
    notice = [
      (pkg ? "Updated" : "Installed"),
      package_name,
      (pkg ? "from version #{pkg[:version].join('.')}" : nil),
      (pkg ? "to" : nil),
      "@latest"
    ].compact.join(' ')
    puts notice
  else
    min_str = minimal_version.present? ? ", required: >= #{minimal_version.join('.')}" : ''
    puts "#{package_name} already installed (#{pkg[:version].join('.')}#{min_str}), skipping."
  end
end