# Attributes

BASE = %w(
  erratum_id:integer
  pdf_page:integer
  bug_type:string
  description:text
)

MORE = %w(
  created_by:string
  fixed_on:datetime
  paper_page:integer
  product_id:integer
  sorting_key:integer
  title_release_fixed_in:integer
  title_release_reported_in:integer
)

EDIT = %w(
  fix_category:string
  fix_comment:string
)

# optionally remove old cruft
if ARGV.first == 'clean'
  require 'fileutils'
  FileUtils.rm_rf 'errata'
  ARGV.shift
end

# establish project
if File.exist? 'errata'
  Dir.chdir 'errata'
else
  system 'rails errata'
  Dir.chdir 'errata'

  system "ruby script/generate scaffold erratum #{BASE.join(' ')}"
  system "ruby script/generate migration AddMoreToErratum #{MORE.join(' ')}"
  system "ruby script/generate migration AddEditToErratum #{EDIT.join(' ')}"
  system 'rake db:migrate'

  # helper for editing files
  def edit(filepath)
    data = File.open(filepath) {|file| file.read} rescue ''
    yield data
    File.open(filepath,'w') {|file| file.write data}
  end

  # add a virtual "beta_page" attribute to the model
  edit('app/models/erratum.rb') do |data|
    data[/^()end/,1] = <<-'EOF'.gsub(/^    /,'')
      def beta_page
        beta = { 896 => 0, 904 => 1, 910 => 2 }
        beta.default = '?'

        "#{beta[title_release_reported_in]}:#{pdf_page}"
      end
    EOF
  end

  # primary index
  edit('app/views/errata/index.html.erb') do |data|
    # rename Pdf page to beta page
    data.gsub! 'Pdf', 'Beta'
    data.gsub! 'pdf', 'beta'

    # highlight new rows
    data[/<tr()>\s+<td>/,1] = '<%= check_age(erratum) %>'

    # delete extra links
    data.gsub! /.* link_to '.*\n/, ''

    # make erratum_id hypertext
    data[/=(h erratum.erratum_id)/,1] = 
      ' link_to erratum.erratum_id, edit_erratum_path(erratum)'
  end

  # erratum helper
  edit('app/helpers/errata_helper.rb') do |data|
    data[/^()end/,1] = <<-'EOF'.gsub(/^    /,'')
      def check_age(erratum)
        if Time.now - erratum.updated_at < 86400
          ' class="new"'
        end
      end
    EOF
  end

  # create a stylesheet
  edit('public/stylesheets/errata.css') do |data|
    data << <<-EOF.gsub(/^      /,'')
      /* row colors */
      .new  {background-color: #9F9}

      /* make the header an eye catcher */
      h1 {
        line-height: 2em;
        text-align: center;
        text-transform: capitalize
      }

      /* center the table */
      table {
        margin-left: auto;
        margin-right: auto
      }

      /* table borders */
      table, td, th {
        border-color: #600;
        border-style: solid;
        border-width: 1px;
      }

      table {
        border-spacing: 0;
        border-collapse: collapse;
      }

      td, th {
        margin: 0;
        padding: 4px;
      }

      tr {
        background-color: #FFC;
      }

      tr.new {
        background-color: yellow
      }
    EOF
  end

  # link the stylesheet
  edit('app/views/layouts/errata.html.erb') do |data|
    data[/stylesheet_link_tag.*() %>/,1] = ", 'errata'"
  end

  # edit erratum
  edit('app/views/errata/edit.html.erb') do |data|
    # make BASE fields readonly
    data.gsub! /f.text_field (\S+)/, 'f.text_field \1, :readonly => true'
    data.gsub! /<%= f.text_area :(\w+) %>/, '<pre><%=h @erratum.\1 %></pre>'

    # add EDIT fields
    data[/\n()\s+<p>\s+<%= f.submit/,1] = <<-EOF.gsub(/^    /,'')
      <p>
        <b>Fix category</b><br />
        <%= f.select :fix_category, %w(FIXED DEFERRED RESOLVED) %>
      </p>

      <p>
        <b>Fix comment</b><br />
        <%= f.text_field :fix_comment %>
      </p>
    EOF
  end

  # filter, order index
  # change update from redirecting to 'show' to redirect to 'next'
  edit('app/controllers/errata_controller.rb') do |data|
    data[/def index\s+@errata = Erratum.find\(:all()\)/,1] = 
     ", :conditions => 'fix_category IS NULL',\n    :order => 'pdf_page'"

    data.gsub! 'redirect_to(@erratum)',
      'redirect_to(:action => index)'
  end

  # disable session support
  edit('app/controllers/application.rb') do |data|
    data[/()^end/,1] = "\n  self.allow_forgery_protection=false\n"
    data[/()^end/,1] = "\n  session :disabled => true\n"
  end
end

require 'rubygems'
require 'config/environment.rb'
require 'rexml/document'
require 'open-uri'

doc = REXML::Document.new(open(ARGV.first))
doc.root.elements.each do |erratum|
  attrs = Hash[*erratum.elements.map {|element|
    name, value = element.name, element.text
    name = 'erratum_id' if name == 'id'
    name.gsub!('-','_')
    value = value.to_i if element.attributes['type'] == 'integer'
    [name, value]
  }.flatten]

  erratum = Erratum.find_by_erratum_id(attrs['erratum_id'])
  erratum ||= Erratum.new
  erratum.update_attributes! attrs
end

system 'ruby script/server'
