#!/usr/bin/env ruby

require 'vpim/vcard'

module Samsung
  VERSION = '0.0.1'

  def self.map_csv_row(ary)
    ary.map { |col| '"' << col.gsub(/"/, '""') << '"' }
  end

  class ContactMapper
    attr_accessor :debug

    CARD_KEY_MAP = %w{
      type name_first name_last 
      phone_cell phone_home phone_work 
      note email url note
    }

    PHONE_KEYS = %w{phone_work phone_home phone_cell}

    def initialize(path)
      data = File.read(path)
      @vcf = Vpim::Vcard.decode(data)
    end

    def to_csv
      ret = block_given? ? nil : []

      @vcf.each do |card|
        user = Hash.new { |h, k| h[k] = '' }
        user['type'] = '-1'
        has_phone = false

        card.entries.each do |e|
          case e.name
          when 'TEL'
            key = 'phone_' << e.param('type')[0]
            user[key] = e.value
            has_phone = true if PHONE_KEYS.include?(key) && e.value =~ /\d/
          when 'N'
            name_args = e.value.split(/;/)
            %w{name_last name_first name_mid}.each_with_index do |key, i|
              user[key] = name_args[i]
            end
          when 'URL'
            user['url'] = e.value
          end
        end

        user.each { |k, v| $stderr.puts "DEBUG: #{k}: #{v}" } if @debug


        if has_phone
          # build csv row
          row = CARD_KEY_MAP.map { |key| user[key] }

          # if a block was given, then pass the raw row,
          # otherwise, map the row to a CSV row and return the results
          if block_given?
            yield row 
          else
            ret << Samsung.map_csv_row(row).join(',')
          end
        end
      end

      # return results
      ret.join("\n")
    end
  end
end

path = ARGV.shift
mapper = Samsung::ContactMapper.new(path)
# mapper.debug = true
puts mapper.to_csv

