module EasyPatch
  module CodesetUtilPatch

    def self.included(base)

      base.class_eval do
        const_set(:ENCODING_EXCEPTIONS, [Encoding::UndefinedConversionError, Encoding::ConverterNotFoundError, Encoding::CompatibilityError].freeze)

        class << self
          def safe_from_utf8(str, encoding)
            begin
              from_utf8(str.to_s, encoding)
            rescue
              str.to_s
            end
          end

          # http://www.redmine.org/issues/24616
          def replace_invalid_utf8(str)
            return str if str.nil?
            str.force_encoding('UTF-8')
            if ! str.valid_encoding?
              str = str.encode('UTF-16LE', :invalid => :replace,
                :undef => :replace, :replace => '?').encode('UTF-8')
            end
            str
          end

          # http://www.redmine.org/issues/24616
          def to_utf8(str, encoding)
            return str if str.nil?
            str.force_encoding('ASCII-8BIT')
            if str.empty?
              str.force_encoding('UTF-8')
              return str
            end
            enc = encoding.blank? ? 'UTF-8' : encoding
            if enc.upcase != 'UTF-8'
              str.force_encoding(enc)
              str = str.encode('UTF-8', :invalid => :replace,
                :undef => :replace, :replace => '?')
            else
              str = replace_invalid_utf8(str)
            end
            str
          end
        end

      end
    end

  end
end
EasyExtensions::PatchManager.register_other_patch 'Redmine::CodesetUtil', 'EasyPatch::CodesetUtilPatch'
