
require 'rubygems'
require 'dm-core'
require 'dm-more'
require 'dm-types'
require 'pp'
require 'benchmark'

NUM_INSTANCE = 10
NUM_CONTEXT = 10
NUM_FACT_PER_CONTEXT = 100

class Xbrlinstance
  include DataMapper::Resource
  property :id, Integer, :serial => true

  property :fpath, Text

  has n, :units
  has n, :contexts
  has n, :facts
  has n, :footnotes
end

class Unit
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance
  has n, :facts

  property :name, String
  property :measure, String,     :default => nil
  property :numerator, String,   :default => nil
  property :denominator, String, :default => nil

end

class Context
  include DataMapper::Resource
  property :id, Integer, :serial => true

  belongs_to :xbrlinstance
  has n, :facts

  property :name, String
  property :identifier, String
  property :period_startDate, Date, :default => nil
  property :period_endDate,  Date, :default => nil
  property :period_instant,  Date, :default => nil
  property :period_forever,  Boolean, :dafault => false

  property :senario, String   # not yet impl
  property :segment, String   # not yet impl

end
   
class Footnote
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance

  property :val, String, :length => 4096 # not yet impl
end

class Fact
  include DataMapper::Resource
  property :id, Integer,  :serial => true

  belongs_to :xbrlinstance

  property :element, String
  property :val, String, :length => 4096

  belongs_to :context   # @contxtRef
  belongs_to :unit      # @unitRef

  def inspect
    super.to_s # +
    #  " contextRef='#{Context.all('id' => self.context_id)[0].name.to_s}'" +
    #  " unitRef='#{Unit.all('id' => self.unit_id)[0].name.to_s}'" +
    #  " val='#{val}'\n"
  end
end

if __FILE__ == $0
  require 'optparse'

  mem_p = false
  init_p = false

  def generate_data
    # instance を登録
    1.upto(NUM_INSTANCE) do |i|
      inst = Xbrlinstance.find_or_create(:fpath => "A-#{i}.xml")
      u1 = inst.units.build(:name => "unit-01", :measure => "measure")

      # fact を登録
      1.upto(NUM_CONTEXT) do |j|
        c = inst.contexts.build(:name => "context-#{j}", :period_instant => Date.new)

        1.upto(NUM_FACT_PER_CONTEXT) do |k|
          f = inst.facts.build(:element => "foo:bar-#{k}", :val => "#{i*10000 + j*1000 + k}")
          u1.facts << f
          c.facts << f
        end
      end
      inst.save
    end
  end

  puts Benchmark.measure {

    opt = OptionParser.new

    opt.on('-m', 'use memory db') {|v| mem_p = true }
    opt.on('-i', 'init db') {|v| init_p = true }

    opt.parse!(ARGV)

    if mem_p
      puts "--- using memory"
      DataMapper.setup(:default, 'sqlite3::memory:''')
      puts "--- init data"
      DataMapper.auto_migrate!
      generate_data()
    else
      puts "--- using file"
      # DataMapper.setup(:default, "sqlite3://#{File.dirname(File.expand_path(__FILE__))}/db.sqlite3")

      # Database を作成しておく必要がある。
      # $ mysql -u root -p
      # > create database dm_test;
      # > quit
      DataMapper.setup(:default, "mysql://root:root@localhost/dm_test")
      if init_p
        puts "--- init data"
        DataMapper.auto_migrate!
        generate_data()
      else
        puts "--- open exist data"
        DataMapper.auto_upgrade!
      end
    end

    # pp Xbrlinstance.first('id' => '2')
    # pp Xbrlinstance.all

    pp Unit.all('name' => 'unit-01').size
    pp Unit.all('xbrlinstance.fpath' => 'A-5.xml', 'name' => 'unit-02').size

    pp Context.all.size
    pp Context.all('xbrlinstance.fpath' => 'A-5.xml').size

    pp Fact.all.size
    pp Fact.all('unit.name' => 'unit-01').size
    pp Fact.all('xbrlinstance.fpath' => 'A-5.xml').size
    pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'context.name' => 'context-9').size
    pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'element' => 'foo:bar-5').size
    pp Fact.all('xbrlinstance.fpath' => 'A-5.xml', 'element' => 'foo:bar-5', 'context.name' => 'context-2').size
  }
end
