# -*- ruby -*-
#
# LDAP Data Interchange Format -- LDIF (described in RFC2849)
# Copyright (C) 2002,2003 Takaaki Tateishi <ttate@users.sourceforge.net>
#
# NOTE:
# DON'T USE THIS LIBRARY, BECAUSE THIS LIBRARY IS NOT COMPLETELY
# IMPLEMENTED YET!
#

module LDAP
  FILL  = /\s*/
  SEP   = /(\r\n)|(\n)/

  module LDIF
    class IllegalFormat < StandardError; end

    module Util
      def multibytes?(str)
	for i in 0..(str.length - 1)
	  if( str[i] & 0x8000 == 0x8000 )
	    return true
	  end
	end
	return false
      end
      
      def b64enc(str)
	[str].pack("m")
      end
      
      def b64dec(str)
	str.unpack("m")[0]
      end

      def split_vals(str)
	str.split(/,/)
      end
    end
    
    class Record
      include Util

      def initialize(spec)
	# @spec = [[attr, {'vals'=>vals, 'lang'=>lang, 'enc'=>enc}], ...]; non-nil
	#   vals = [val, ...]; non-nil
	#   enc  = ":"(b64) or "<"(url) or nil
	@spec = []
      end

      def attrs
        attrs = []
	@spec.each{|attr,data|
	  case data['enc']
	  when ":"
	    vals = split_vals(b64dec(data['vals'][0]))
	  when "<"
	    if( data['vals'][0] =~ /file:\/\/(.+)/ )
	      filename = $1
	    else
	      filename = data['vals'][0]
	    end
	    val = File.open(filename){|f| f.read }
            vals = [val]
          else
            vals = data['vals']
	  end
          attrs.push([attr,vals])
	}
        attrs
      end

      def dn
        aref("dn").join(", ")
      end

      def changetype
        ct = aref("changetype")
        if( ct )
          ct[0]
        else
          nil
        end
      end

      def aref(key)
	vals = []
	@spec.each{|attr,data|
	  if( attr == key )
	    vals += data['vals']
	  end
	}
	return vals
      end

      def to_mods
        mods = []
        ct   = LDAP::LDAP_MOD_ADD
        attrs.each{|attr,vals|
          case attr
          when 'changetype'
            case vals[0]
            when 'add'
              ct = LDAP::LDAP_MOD_ADD
            when 'dele', 'delete'
              ct = LDAP::LDAP_MOD_DELETE
            when 'replace', 'modify'
              ct = LDAP::LDAP_MOD_REPLACE
            end
          else
            mods.push(LDAP::LDAPMod.new(ct, attr, vals))
          end
        }
        mods
      end
    end

    class LDIF
      def initialize()
	@record  = []
	@version = 1
      end

      def from_entries
      end

      def to_mods
      end

      def to_s
      end

      def parse_version_spec(str)
	if( str =~ /^version:\s*(\d+)/ )
	  @version = $1.to_i
	else
	  raise(IllegalFormat, "version:")
	end
      end
    end
  end
end
