require 'toml'

provides :parity_node

property :name, String, name_property: true, required: true
property :config, Hash, required: true
property :password, String, required: true
property :rpc_proxy_port, Integer

action :enable do
  node_name = name
  parity_service = "parity_#{node_name}"
  base_path = "#{node['kosmos-parity']['home_path']}/.local/share/io.parity.ethereum/#{node_name}"
  config_path = "#{base_path}/config.toml"

  config[:parity][:base_path] = base_path
  config[:account] = {}
  config[:account][:password] = ["#{base_path}/password"]

  if config[:parity][:chain] == "dev"
    config[:parity][:chain] = "#{base_path}/chain-config.json"
  end

  directory base_path do
    recursive true
    owner     "parity"
    group     "parity"
  end

  %w(chains keys).each do |subfolder|
    directory "#{base_path}/#{subfolder}" do
      recursive true
      owner     "parity"
      group     "parity"
    end
  end

  password_path = "#{base_path}/password"

  file password_path do
    content password
    owner   "parity"
    group   "parity"
    mode    0640
  end

  ruby_block "generate config" do
    block do
      parity_args = "--chain #{config[:parity][:chain]} --base-path #{base_path}"

      parity_account_list = Mixlib::ShellOut.new(
        "parity account list #{parity_args}",
        user: "parity"
      )
      parity_account_list.run_command

      parity_account = parity_account_list.stdout.strip.gsub(/[(\[|\])]/, '')

      if parity_account.empty?
        parity_account_create = Mixlib::ShellOut.new(
          "parity account new #{parity_args} --password #{base_path}/password",
          user: "parity"
        )
        parity_account_create.run_command

        parity_account = parity_account_create.stdout.strip
      end

      config[:account][:unlock] = [parity_account]

      # Using our own chain config (i.e. dev)
      if config[:parity][:chain].include?(".json")
        template "#{base_path}/chain-config.json" do
          source 'chain-config.json.erb'
          variables parity_account: parity_account
          owner     "parity"
          group     "parity"
          mode      0640
          notifies :restart, "service[#{parity_service}]", :delayed
        end
      end

      file "config" do
        path      config_path
        content   TOML::Generator.new(config).body
        owner     "parity"
        group     "parity"
        mode      0640
        notifies :restart, "service[#{parity_service}]", :delayed
      end
    end
  end

  execute "systemctl daemon-reload" do
    command "systemctl daemon-reload"
    action :nothing
  end

  template "/lib/systemd/system/#{parity_service}.service" do
    source "parity.systemd.service.erb"
    variables config_file: config_path
    notifies :run, "execute[systemctl daemon-reload]", :delayed
    notifies :restart, "service[#{parity_service}]", :delayed
  end

  service parity_service do
    action [:enable, :start]
  end

  if rpc_proxy_port
    include_recipe "kosmos-nginx"

    hostname = node['kosmos-parity']['hostname']

    template "#{node['nginx']['dir']}/sites-available/#{parity_service}" do
      source 'nginx_conf_parity.erb'
      owner 'www-data'
      mode 0640
      variables internal_port: config[:rpc][:port],
                external_port: rpc_proxy_port,
                parity_service: parity_service,
                server_name:   hostname,
                ssl_cert:      "/etc/letsencrypt/live/#{hostname}/fullchain.pem",
                ssl_key:       "/etc/letsencrypt/live/#{hostname}/privkey.pem"
      notifies :reload, 'service[nginx]', :delayed
    end

    nginx_site parity_service do
      action :enable
    end

    nginx_certbot_site hostname do
      site parity_service
    end
  end
end
