require 'rake/rdoctask'
require 'rake/testtask'
require 'rake/gempackagetask'

# Initialize some variables.

readme = File.read('README')
Release = (readme[/^= (.+) README$/, 1] || 'unknown').downcase.tr(" ", "-")
Name = Release[/\D+/].sub(/\-+$/, '') || 'unknown'
Version = Release[/[\d.]+/] || 'unknown'

AuthorName, AuthorMail = 'George Moschovitis', 'gm@navel.gr'
RubyVersion = '1.8.2' 

# Description = (readme[/README\s+(.+?)\n\n/m, 1] || "unknown").gsub(/\s+/, " ")
# Summary = Description[/^.+?>/] || "unknown"

# DocFiles = %w(README NEWS TODO COPYING GPL)
# RDocFiles = DocFiles - %w(GPL)
RDocOpts = ["--inline-source", "--line-numbers","--title", Name ]
# AdditionalFiles = DocFiles + %w(setup.rb)
VersionFile = MainFile = File.join("lib", Name + '.rb')

RubyForgeProject = 'nitro' 
RubyForgeUser = 'gmosx'
Homepage = "http://#{RubyForgeProject}.rubyforge.org/"

task :default => :package

# Run the tests.

Rake::TestTask.new do |t|
	t.libs << 'test'
	t.test_files = FileList['test/**/tc*.rb']
	t.verbose = true
end

# Generate RDoc documentation.

Rake::RDocTask.new do |rd|
	rd.main = 'README'
	rd.rdoc_dir = 'rdoc'
	rd.rdoc_files.include('README', 'INSTALL', 'doc/config.txt', 'doc/tutorial.txt', 'lib/**/*.rb')
	rd.options << '--all --inline-source'
end

# Build gem.

spec = Gem::Specification.new do |s|
	s.name = 'og'
	if File.read('lib/og.rb') =~ /Version\s+=\s+'(\d+\.\d+\.\d+)'/
		s.version = $1 
	else
		raise 'No version found'
	end
	s.summary = 'Og (ObjectGraph)'
	s.description = 'An efficient and transparent Object-Relational mapping library'
	
	s.add_dependency 'glue', "= #{s.version}"
	s.add_dependency 'facets', '>= 0.7.1'
	#s.add_dependency 'postgres-pr', '>= 0.3.0'
	#s.add_dependency 'postgres', '>= 0.7.1'
	#s.add_dependency 'sqlite3-ruby', '>= 1.0.0'
	#s.add_dependency 'mysql', '>= 2.5.1'

	s.required_ruby_version = '>= 1.8.2'

	s.files = FileList[
		'[A-Z]*', 'install.rb', '{bin,benchmark,examples,doc,lib,test,vendor}/**/*' 
	].exclude('.svn/**/*').exclude('**/*.log').to_a

	s.require_path = 'lib'
	s.autorequire = 'og'
	
	s.has_rdoc = true
	s.extra_rdoc_files = FileList['README', 'doc/RELEASES', 'doc/LICENSE', 'doc/AUTHORS'].to_a
	s.rdoc_options << '--main' << 'README' << '--title' << 'Og Documentation'
	s.rdoc_options << '--all' << '--inline-source'

	s.author = 'George Moschovitis'
	s.email = 'gm@navel.gr'
	s.homepage = 'http://nitro.rubyforge.org'
	s.rubyforge_project = 'nitro'
end

Rake::GemPackageTask.new(spec) do |pkg|
  pkg.package_dir = 'dist'
  pkg.need_zip = true
  pkg.need_tar = true
end

# Manual install (not recommended).

task :install do
  ruby 'install.rb'
end

# Release files to Rubyforge.
# The code for this task provided by Florian Gross.

desc "Publish the release files to RubyForge."
task :publish => [:package] do
  files = ['gem', 'tgz', 'zip'].map { |ext| "dist/#{Release}.#{ext}" }

  if RubyForgeProject then
    require 'net/http'
    require 'open-uri'

    changes = ''
    if File.exist?('doc/RELEASES') then
      changes_re = /^== \s+ Version \s+ #{Regexp.quote(Version)} \s*
                    (.+?) (?:==|\Z)/mx
      changes = File.read('doc/RELEASES')[changes_re, 1] || ''
    end

    project_uri = "http://rubyforge.org/projects/#{RubyForgeProject}/"
    project_data = open(project_uri) { |data| data.read }
    group_id = project_data[/[?&]group_id=(\d+)/, 1]
    raise "Couldn't get group id" unless group_id

    print "#{RubyForgeUser}@rubyforge.org's password: "
    password = STDIN.gets.chomp

    login_response = Net::HTTP.start('rubyforge.org', 80) do |http|
      data = [
        "login=1",
        "form_loginname=#{RubyForgeUser}",
        "form_pw=#{password}"
      ].join("&")
      http.post('/account/login.php', data)
    end

    cookie = login_response['set-cookie']
    raise 'Login failed' unless cookie
    headers = { 'Cookie' => cookie }

    release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
    release_data = open(release_uri, headers) { |data| data.read }
    package_id = release_data[/[?&]package_id=(\d+)/, 1]
    raise "Couldn't get package id" unless package_id

    first_file = true
    release_id = ""

    files.each do |filename|
      basename = File.basename(filename)
      file_ext = File.extname(filename)
      file_data = File.open(filename, "rb") { |file| file.read }

      puts "Releasing #{basename}..."

      release_response = Net::HTTP.start('rubyforge.org', 80) do |http|
        release_date = Time.now.strftime('%Y-%m-%d %H:%M')
        type_map = {
          '.zip'    => '3000',
          '.tgz'    => '3110',
          '.gz'     => '3110',
          '.gem'    => '1400',
          '.md5sum' => '8100'
        }; type_map.default = '9999'
        type = type_map[file_ext]
        boundary = 'rubyqMY6QN9bp6e4kS21H4y0zxcvoor'

        query_hash = if first_file then
          {
            'group_id' => group_id,
            'package_id' => package_id,
            'release_name' => Release,
            'release_date' => release_date,
            'type_id' => type,
            'processor_id' => '8000', # Any
            'release_notes' => '',
            'release_changes' => changes,
            'preformatted' => '1',
            'submit' => '1'
          }
        else
          {
            'group_id' => group_id,
            'release_id' => release_id,
            'package_id' => package_id,
            'step2' => '1',
            'type_id' => type,
            'processor_id' => '8000', # Any
            'submit' => 'Add This File'
          }
        end

        query = '?' + query_hash.map do |(name, value)|
          [name, URI.encode(value)].join('=')
        end.join('&')

        data = [
          "--" + boundary,
          "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
          "Content-Type: application/octet-stream",
          "Content-Transfer-Encoding: binary",
          "", file_data, ""
          ].join("\x0D\x0A")

        release_headers = headers.merge(
          'Content-Type' => "multipart/form-data; boundary=#{boundary}"
        )

        target = first_file ? '/frs/admin/qrs.php' : '/frs/admin/editrelease.php'
        http.post(target + query, data, release_headers)
      end

      if first_file then
        release_id = release_response.body[/release_id=(\d+)/, 1]
        raise("Couldn't get release id") unless release_id
      end

      first_file = false
    end
  end
end
