# frozen_string_literal: true

# This file is part of RASN1
# See https://codeberg.org/lemontree55/rasn1 for more informations
# Copyright (C) 2016-2024 Sylvain Daubert <sylvain.daubert@laposte.net>
# Copyright (C) 2024 LemonTree55 <lenontree@proton.me>
# This program is published under MIT license.

require 'date'

module RASN1
  module Types
    # ASN.1 UTCTime
    #
    # +{#value} of a +UtcTime+ should be a ruby Time.
    #
    # Unlike {GeneralizedTime}, a UTCTime serializes only 2 digits for years.
    # Unlike its name, a UTCTime may contain a local time.
    #
    # ===Notes
    # When encoding, resulting string is always a UTC time, appended with +Z+.
    # Seconds are always generated.
    #
    # On parsing, UTC times (ending with +Z+) and local times (ending with
    # +sHHMM+, where +s+ is +++ or +-+, and +HHMM+ is the time differential
    # betwen UTC and local time) are both supported. Seconds may be present or
    # not.
    # @author Sylvain Daubert
    class UtcTime < Primitive
      # UtcTime id value
      ID = 23

      # Get ASN.1 type
      # @return [String]
      def self.type
        'UTCTime'
      end

      # Make time value from +der+ string
      # @param der [String]
      # @param ber [::Boolean]
      # @return [void]
      # @raise [ASN1Error] unrecognized  time format
      def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
        format = case der.size
                 when 11, 15
                   '%Y%m%d%H%M%z'
                 when 13, 17
                   '%Y%m%d%H%M%S%z'
                 else
                   prefix = @name.nil? ? type : "tag #{@name}"
                   raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
                 end
        century = (Time.now.year / 100).to_s
        begin
          @value = Strptime.new(format).exec(century + der)
        rescue ArgumentError
          prefix = @name.nil? ? type : "tag #{@name}"
          raise ASN1Error, "#{prefix}: unrecognized format: #{der}"
        end
      end

      private

      # @return [String]
      def value_to_der
        @value.getutc.strftime('%y%m%d%H%M%SZ')
      end

      # @return [String]
      def trace_data
        return super if explicit?

        +'    ' << raw_data
      end
    end
  end
end
