#!/usr/bin/env ruby
# frozen_string_literal: true

require 'fileutils'
require 'securerandom'
require 'digest/sha2'
# below are the methods needed for atome creation and run

def found_path(arg_name)
  project_name = ARGV[ARGV.find_index(arg_name) + 1]
  path = `pwd`.chomp
  if project_name != 'run' && project_name != 'guard' && !project_name.nil? &&
    project_name != 'port:' && project_name != 'server' && project_name != 'build'
    path = "#{path}/#{project_name}"
  end
  path
end

def delete_all(dir, user_application = false)
  Dir.foreach(dir) do |e|
    next if %w[. ..].include? e

    full_name = dir + File::Separator + e
    if FileTest.directory?(full_name)
      delete_all(full_name, user_application) if user_application && dir != 'application'
    else
      File.delete(full_name)
    end
  end
  Dir.delete(dir) if user_application && dir != 'application'
end

def build_app(path, production)
  # now run the rake task to build the needed libraries (atome, renderers, etc...)
  app_builder_helpers = File.join(File.dirname(__FILE__), '../app_builder_helpers')
  # now run the rake task to compile user code to javascript
  `cd #{app_builder_helpers};rake build_user_code[#{path},#{production}]`
end

def create_application(project_name, force, production)
  # print "directory already exist, use force to overwrite"
  new_app_creation = false
  current_path = `pwd`.chomp
  unless force && File.directory?(project_name)
    new_app_creation = true
    Dir.mkdir project_name
    # now lets create the application identity
    uuid = SecureRandom.uuid
    sha = Digest::SHA256.hexdigest(uuid)
    coded_id = sha.gsub('-', '_')
    added_content = <<~STR
      class Atome
        def self.aui
          "#{coded_id}"
        end
      end
    STR
    file_location = "#{current_path}/#{project_name}/aui.rb"
    File.new file_location, 'w'
    File.open(file_location, 'w') do |f|
      f.puts added_content
    end
  end

  gem_assets_location = File.join(File.dirname(__FILE__), '../vendor/assets/')
  app_builder_helpers = File.join(File.dirname(__FILE__), '../app_builder_helpers')
  target_template_location = "#{current_path}/#{project_name}"
  Dir.entries(gem_assets_location).select do |entry|
    if File.join(entry) && !%w[. ..].include?(entry)
      entry = "#{File.dirname(__FILE__)}/../vendor/assets/#{entry}"
      FileUtils.cp_r entry, target_template_location
    end
  end
  # now run the rake task to build the needed libraries (atome, renderers, etc...)
  `cd #{app_builder_helpers};rake system_builder[#{current_path}/#{project_name},#{production}]`
  if new_app_creation
    # now adding name to the app
    index_html = "#{current_path}/#{project_name}/build/index.html"
    index_html_content = File.open(index_html).read
    index_html_content = index_html_content.gsub('<title>atome</title>', "<title>#{project_name}</title>")
    File.open(index_html, 'w') do |f|
      f.puts index_html_content
    end
  end
end

def update_application(project_name, production)
  app_builder_helpers = File.join(File.dirname(__FILE__), '../app_builder_helpers')
  `cd #{app_builder_helpers};rake system_updater[#{project_name},#{production}]`
end

def guard_check
  loop do
    sleep 9
  end
  nil unless ARGV.include?('guard')
end

def run_application(build_target, location, port = 9292)
  case build_target
  when :server
    threads = []
    threads << Thread.new do
      sleep 1.5
      `open http://localhost:9292/index`
    end
    `cd #{location}/server;rackup --server puma --port #{port}  --env production`
  when :browser
    `cd #{location}/build;open index.html`
    guard_check
  when :native
    # freebsd
  when :linux
    # freebsd
  when :osx
    # osx
  when :windows
    # windows
  else
    `cd #{location}/build;open index.html`
    guard_check
  end
end

# below we analyse the ARGV
location = '/'
force = nil
production = nil
port = 9292

production = 'production' if ARGV.include?('production')

force = 'force' if ARGV.include?('force')

port = ARGV[ARGV.find_index('port:') + 1] if ARGV.include?('port:')

platforms = %w[android browser server osx freebsd ios linux osx windows]
# now setting build_target

build_target = 'browser'

platforms.each do |platform|
  build_target = platform if ARGV.include?(platform)
end

if ARGV.include?('create')
  project_name = ARGV[1]
  location = "/#{project_name}"
  create_application(project_name, force, production)
end

if ARGV.include?('build')
  path = found_path('build')
  build_app(path, production)
end

if ARGV.include?('update')
  # TODO: also update index.html and all other files except the application folder
  path = found_path('update')
  update_application(path, production)
end

if ARGV.include?('guard')
  Thread.new do
    sleep 1.2
    Dir.chdir("./#{location}") do
      `guard`
    end
  end
end

if ARGV.include?('run')
  path = if location != '/'
           "#{`pwd`.chomp}/#{location}"
         else
           found_path('run')
         end

  case build_target
  when 'android'
    # TODO: write code here
  when 'browser'
    run_application(:browser, path)
  when 'freebsd'
    # TODO: write code here
  when 'ios'
    # TODO: write code here
  when 'linux'
    # TODO: write code here
  when 'osx'
    run_application(:osx, path)
  when 'server'
    config_location = "#{path}/server/config.ru"
    file = File.open(config_location)
    text = file.read
    text = text.gsub('run Unreloader', '')
    text = text.gsub('run App.freeze.app', '')
    text = text.gsub(/^$\n/, '')
    text = if production == 'production'
             "#{text}run App.freeze.app"
           else
             "#{text}run Unreloader"
           end
    File.open(config_location, 'w') do |f|
      f.puts text
    end
    run_application(:server, path, port)
  when 'windows'
    # TODO: write code here
  else
    run_application(:browser, path)
  end

end