# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

require 'contrast/utils/os'

module Contrast
  # A Rake task designed to allow control of the Contrast Service as a stand
  # alone executable rather than one managed by the Agent running in a process
  # forked from the application
  module Service
    extend Rake::DSL
    # Start the service if it is not already running
    def self.start_service
      puts 'Starting Contrast Service'
      service_log = ::Contrast::CONTRAST_SERVICE.logger_path
      if File.writable?(service_log)
        spawn('contrast_service', out: File::NULL, err: service_log)
      else
        spawn('contrast_service', %i[out err] => File::NULL)
      end

      watcher = Contrast::Agent::Thread.new do
        sleep(0.05) until Contrast::Utils::OS.running?
      end
      watcher.join(1)
      puts Contrast::Utils::OS.running? ? 'Contrast Service started successfully.' : 'Contrast Service did not start.'
    end

    # Stop the service if it is running
    def self.stop_service
      pid = `ps aux | grep contrast-servic[e] | awk '{print $2}'`
      `kill #{ pid }` if pid
    end

    namespace :contrast do
      namespace :service do
        desc 'Starts the Contrast Service'
        task :start do
          if Contrast::Utils::OS.running?
            puts 'Contrast Service already running. No need to start'
          else
            start_service
          end
        end
      end
    end

    namespace :contrast do
      namespace :service do
        desc 'Prints the status of the Contrast Service'
        task :status do
          if Contrast::Utils::OS.running?
            puts 'online'
          else
            puts 'offline'
          end
        end
      end
    end

    namespace :contrast do
      namespace :service do
        desc 'Stops the Contrast Service'
        task :stop do
          if Contrast::Utils::OS.running?
            puts 'Stopping Contrast Service'
            stop_service
            watcher = Contrast::Agent::Thread.new do
              sleep(0.05) while Contrast::Utils::OS.running?
            end
            watcher.join(1)
            if Contrast::Utils::OS.running?
              puts 'Contrast Service did not stop.'
            else
              puts 'Contrast Service stopped successfully.'
            end
          else
            puts 'Contrast Service is not already running. No need to stop.'
          end
        end
      end
    end
  end
end