# frozen_string_literal: true

# This module provides classes for the Makit gem.
module Makit
  class Humanize
    def self.get_humanized_size(bytes, precision = 2)
      units = ["B", "KB", "MB", "GB", "TB", "PB"]
      return "0 B" if bytes == 0

      exp = (Math.log(bytes) / Math.log(1024)).to_i
      exp = units.size - 1 if exp >= units.size

      size = bytes.to_f / (1024 ** exp)
      format("%.#{precision}f %s", size, units[exp])
    end

    def self.get_make_result_summary(make_result)
      summary = "Make Result\n"
      summary += "  Repository: #{make_result.repository}\n"
      summary += "  Commit: #{make_result.commit}\n"
      summary += "  Branch: #{make_result.branch}\n"
      summary += "  Tag: #{make_result.tag}\n"
      summary += "  Device: #{make_result.device}\n"
      summary += "  Runtime Identifier: #{make_result.runtime_identifier}\n"
      summary += "  Initial Size: #{get_humanized_size(make_result.initial_size)}\n"
      summary += "  Final Size: #{get_humanized_size(make_result.final_size)}\n"
      summary += "  Delta Size: #{get_humanized_size(make_result.final_size - make_result.initial_size)}\n"
      summary += "  Commands: (#{make_result.commands.length})\n"
      make_result.commands.each do |command|
        details = get_command_details(command)
        summary += "\n"
        summary += indent_string(details, 4)
        summary += "\n"
      end

      summary
    end

    def self.get_commands(commands)
      message = ""
      commands.each do |command|
        message += Makit::Humanize::get_command_details(command)
      end
      message
    end

    def self.get_command_summary(command)
      symbol = Makit::Symbols.warning
      symbol = Makit::Symbols.checkmark if !command.exit_code.nil? && command.exit_code.zero?
      symbol = Makit::Symbols.error if command.exit_code != 0
      "#{symbol} #{command.name} #{command.arguments.join(" ")}"
    end

    def self.get_command_details(command)
      summary = "#{get_command_summary(command)}\n"
      summary += "  Name: #{command.name}\n"
      summary += "  Arguments: #{command.arguments.join(" ")}\n"
      summary += "  Directory: #{command.directory}\n"
      summary += "  Exit Code: #{command.exit_code}\n"
      if command.output.length > 0
        summary += "  Output:\n"
        summary += indent_string(command.output, 4)
        summary += "\n"
      end
      if command.error.length > 0
        summary += "  Error:\n"
        summary += indent_string(command.error, 4)
        summary += "\n"
      end
      summary
    end

    def self.indent_string(string, spaces)
      string.split("\n").map { |line| " " * spaces + line }.join("\n")
    end

    def self.get_protobuf_timestamp(timestamp)
      Time.at(timestamp.seconds, timestamp.nanos / 1000.0).strftime("%Y-%m-%d %H:%M:%S")
    end

    def self.get_protobuf_duration(duration)
      total_seconds = duration.seconds + (duration.nanos / 1_000_000_000.0)
      hours = (total_seconds / 3600).to_i
      minutes = ((total_seconds % 3600) / 60).to_i
      seconds = (total_seconds % 60).round(2)
      "#{hours}h #{minutes}m #{seconds}s"
    end
  end
end