# frozen_string_literal: true

require 'thor' class Hammer < Thor

include Thor::Actions
source_root '.'

end

class Hash

def method_missing(methodname, *params)
  if self.class == Hash
    self[methodname]||self[methodname.to_s]
  else
    super
  end
end

end

namespace :rancher do

rancherconfig = ENV['RANCHER_CONFIG'] || 'rancher/rancherconfig.json'
dockerconfig = 'docker/dockerconfig.json'
config = File.exist?(rancherconfig) ? JSON.parse(File.read(rancherconfig)) : {}
docker_config = JSON.parse(File.read(dockerconfig))
docker_file = ENV['RANCHER_DOCKER_FILE'] || docker_config.rancher_yml || docker_config.prod_yml
rancher_file = 'rancher/rancher-compose.yml'
tag = ENV['TAG'] || 'latest'
RANCHER = "rancher -c #{rancherconfig}".freeze
File.write('rancher/.env.tmp', "TAG=#{tag}")
RANCHER_UP = [
  RANCHER,
  'up',
  "-s #{config.stack}",
  "-f #{docker_file}",
  "-rancher-file #{rancher_file}",
  '-e rancher/.env.tmp'
].join(' ')

desc 'rancher up current service'
task :up_service, [:service] do |_t, _args|
  exec_cmd(RANCHER_UP.to_s,
           '--upgrade',
           '--pull',
           _args[:service] || docker_config.service_name)
end

desc 'rancher restart service'
task :restart, [:service] do |_t, _args|
  exec_cmd(RANCHER.to_s,
           'restart',
           "#{config.stack}/#{_args[:service] || docker_config.service_name}")
end

desc 'rancher upall'
task :up, [:deamon] do |_t, _args|
  exec_cmd(RANCHER_UP,
           '--upgrade',
           "--pull #{_args[:deamon]}")
end
desc 'rancher inspect stack'
task :inspect, [:opt] do |_t, _args|
  exec_cmd(RANCHER, 'inspect', '-a')
end

desc 'rancher rm service'
task :rm do |_t, _args|
  exec_cmd(RANCHER,
           'rm',
           "#{config.stack}/#{docker_config.service_name}")
end

desc 'rancher rm stack'
task :rm_stack do |_t, _args|
  exec_cmd(RANCHER,
           'rm',
           config.stack)
end

desc 'rancher rollback service'
task :rollback, [:service] do |_t, _args|
  exec_cmd(RANCHER_UP,
           '-r',
           _args[:service] || docker_config.service_name)
end

desc 'rancher upgrade'
task :upgrade_service, [:service] do |_t, _args|
  exec_cmd(RANCHER_UP,
           '--force-upgrade',
           '--pull',
           '-d',
           _args[:service] || docker_config.service_name)
end

desc 'rancher upgrade-all'
task :upgrade do |_t, _args|
  exec_cmd(RANCHER_UP, '--force-upgrade', '--pull')
end

desc 'rancher confirm upgrade'
task :confirm, [:service] do |_t, _args|
  exec_cmd(RANCHER_UP,
           '--confirm-upgrade',
           _args[:service] || docker_config.service_name)
end

desc 'rancher export'
task :export do |_t, _args|
  exec_cmd(RANCHER, 'export', config.stack)
end

desc 'rancher host'
task :host do |_t, _args|
  exec_cmd(RANCHER, 'host', '-a')
end

desc 'rancher ls container'
task :lsc do |_t, _args|
  exec_cmd(RANCHER, 'ps', '-c')
end

desc 'rancher ls service'
task :lss do |_t, _args|
  exec_cmd(RANCHER, 'ps', '-a')
end

desc 'rancher ls stacks'
task :lsk do |_t, _args|
  exec_cmd(RANCHER, 'stacks')
end

desc 'rancher ps service'
task :ps, [:service] do |_t, _args|
  result = exec_cmd(RANCHER,
                    'inspect',
                    _args[:service] || "#{config.stack}/#{docker_config.service_name}",
                    capture: true)
  puts(JSON.pretty_generate(JSON.parse(result)))
end

desc 'rancher ps stack'
task :psk do |_t, _args|
  result = exec_cmd(RANCHER, 'inspect', config.stack, capture: true)
  puts(JSON.pretty_generate(JSON.parse(result)))
end

desc 'rancher ls volume'
task lsv: [:volume] do |_t, _args|
end

desc 'rancher logs'
task :logs, [:container] do |_t, _args|
  exec_cmd(RANCHER, 'logs', "#{config.stack}/#{docker_config.service_name}")
end

desc 'rancher exec'
task :exec, [:container, :cmd] do |_t, _args|
  exec_cmd(RANCHER,
           '-i',
           '-t',
           _args[:container],
           _args[:cmd] || '/bin/bash')
end

desc 'rancher volume'
task :volume, [:cmd] do |_t, _args|
  exec_cmd(RANCHER,
           'volume',
           _args[:cmd] || 'ls')
end

desc 'show rancher config'
task :info do
  puts JSON.pretty_generate(config)
end

desc 'dump rancher task '
task :dump do
  target_path = hammer.ask('target path?:')
  hammer.directory('./rancher', "#{target_path}/rancher")
  hammer.copy_file('./lib/tasks/rancher.rake', "#{target_path}/rancher/rancher.rake")
  target_rakefile = "#{target_path}/Rakefile"
  File.open(target_rakefile, 'a') do |f|
    f.puts "import 'rancher/rancher.rake'"
  end
  hammer.directory('bin/rancher', "#{target_path}/bin")
end

private

def exec_cmd(*cmdstr, **opt)
  hammer.say cmdstr.join(' ')
  ret = hammer.run(cmdstr.join(' '), opt)
  exit -1 unless ret
  ret
end

def hammer
  Hammer.new
end

end