#!/usr/bin/env ruby
require "fileutils"
require "json"

APP_ROOT = File.expand_path("..", __dir__)
APP_NAME = "decidim-development-app"

def system!(env = {}, *args)
  if args.empty?
    # env is actually the command
    system(env, exception: true)
  else
    system(env, *args, exception: true)
  end
end

class CodespacesConfig
  ENV_FILE = "/workspaces/.codespaces/shared/environment-variables.json"
  APP_CONFIG = "development_app/config/application.rb"

  def self.running?
    File.exist?(ENV_FILE)
  end

  def initialize
    @hostname = nil
  end

  def hostname
    @hostname ||= fetch_hostname
  end

  def env_vars
    hostname ? { "DECIDIM_HOST" => hostname } : {}
  end

  def configure_application!
    return unless hostname
    return unless File.exist?(APP_CONFIG)

    config_content = File.read(APP_CONFIG)
    return if config_content.match?(/^\s+config\.hosts/)

    updated_content = config_content.sub(
      /(config\.load_defaults\s+[\d.]+\s*\n)/,
      "\\1    config.hosts << \"#{hostname}\"\n"
    )

    File.write(APP_CONFIG, updated_content)
    puts "\n== Configured Codespaces host: #{hostname} =="
  end

  private

  def fetch_hostname
    return nil unless File.exist?(ENV_FILE)

    env_data = JSON.parse(File.read(ENV_FILE))
    codespace_name = env_data["CODESPACE_NAME"]
    return nil unless codespace_name

    "#{codespace_name}-3000.app.github.dev"
  end
end

FileUtils.chdir APP_ROOT do
  # This script is a way to set up or update your development environment automatically.
  # This script is idempotent, so that you can run it at any time and get an expectable outcome.
  # Add necessary setup steps to this file.

  puts "== Installing dependencies =="
  system! "gem install bundler --conservative"
  system("bundle check") || system!("bundle install")
  system("npm install")

  puts "\n== Preparing decidim development app =="
  if CodespacesConfig.running?
    codespaces = CodespacesConfig.new
    system!(codespaces.env_vars, "bundle exec rake development_app") unless Dir.exist?("development_app")
    codespaces.configure_application!
  else
    system!("bundle exec rake development_app") unless Dir.exist?("development_app")
  end

  puts "\n== Preparing database =="
  system("bin/rails db:create")

  if File.exist?("development_app/tmp/pids/server.pid")
    puts "\n== Removing the leftover pid file =="
    system("rm development_app/tmp/pids/server.pid")
  end

  puts "\n== Starting application server =="
  system! "bin/dev"
end
