#!/usr/bin/env ruby # frozen_string_literal: true require 'dotenv' require 'debug' require_relative '../lib/utils/system_information_gather' require_relative '../lib/utils/database_manager' require_relative '../lib/utils/first_run_init' require_relative '../lib/utils/utilities' require_relative '../lib/utils/logg_man' require_relative '../lib/utils/alert_queue_manager' require_relative '../lib/utils/alert_manager' include Utilities # rubocop:disable Style/MixinUsage # binding.b(do: 'irb') @loggman = LoggMan.new begin # Create .env file if it doesn't exist File.open('.env', 'w') {} unless File.exist?('.env') # Load environment variables from .env file Dotenv.load # Initialize AlertQueueManager, RingBuffer, and AlertManager @alert_queue_manager = AlertQueueManager.new(@loggman) # Initialize DatabaseManager db_manager = DatabaseManager.new(@loggman, @alert_queue_manager) # Get database details from environment variables db_details = { username: ENV['DB_USERNAME'], password: ENV['DB_PASSWORD'], key: ENV['DB_SECRET_KEY'], database: ENV['DB_DATABASE'] } # Decrypt password dec_pass = decrypt_string_chacha20(db_details[:password], db_details[:key]) # If any of the necessary details are missing, run the first run setup if db_details.values.any?(&:nil?) @loggman.log_warn('Missing or incomplete configuration. Running first run setup.') first_run_init = FirstRunInit.new(@loggman, @alert_queue_manager, db_manager) first_run_init.run # Reload environment variables after first run setup Dotenv.load db_details = { username: ENV['DB_USERNAME'], password: ENV['DB_PASSWORD'], key: ENV['DB_SECRET_KEY'], database: ENV['DB_DATABASE'] } # Decrypt password again after potentially updating config dec_pass = decrypt_string_chacha20(db_details[:password], db_details[:key]) end # Test connection unless db_manager.test_db_connection(db_details[:username], dec_pass, db_details[:database]) @loggman.log_warn('Failed to connect to the database with existing configuration. Please re-enter your details.') first_run_init = FirstRunInit.new(@loggman, @alert_queue_manager, db_manager) first_run_init.run # Reload environment variables after potentially updating config Dotenv.load db_details = { username: ENV['DB_USERNAME'], password: ENV['DB_PASSWORD'], key: ENV['DB_SECRET_KEY'], database: ENV['DB_DATABASE'] } # Decrypt password again after potentially updating config dec_pass = decrypt_string_chacha20(db_details[:password], db_details[:key]) end # Test connection again after potentially updating config if db_manager.test_db_connection(db_details[:username], dec_pass, db_details[:database]) @loggman.log_info('Successfully connected to the database.') else @loggman.log_error('Failed to connect to the database. Please check your configuration.') exit 1 end @loggman.log_warn('Program successfully ran with no errors') # TODO: Add the rest of application logic here # End of the program # wait for the alert_queue_manager to block before we exit. @alert_queue_manager.shutdown # Shush Rubocop. I know I shouldn't rescue an exception. I am just using it to log exceptions so the # program doesn't crash silently rescue Exception => e # rubocop:disable Lint/RescueException # Log the exception @loggman.log_error("An unhandled exception has occurred: #{e.class}: #{e.message}") @loggman.log_error(e.backtrace.join("\n")) # Re-raise the original exception raise end