#!/usr/bin/ruby

require 'cgi'
require 'iconv'

class App

  def initialize
    @cgi = CGI.new
    @resp = ['text/plain', 'something is wrong if you see this']
    @xml = nil
    @msgs = []
  end

  def selfurl
    @cgi.script_name
  end

  def toppage
    @resp = ['text/html', <<TOPPAGE]
<html>
<head>
<title>WIS Metadata Validator</title>
</head>
<body>
<h1>WIS Metadata Validator</h1>
<h2>(1) upload file:</h2>
<p>
<form action="#{selfurl}" method="POST" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="Upload" />
</form>
</p>
<h2>(2) type XML:</h2>
<p>
<form action="#{selfurl}" method="POST">
<textarea name="xml" rows="20" cols="80">type XML here</textarea>
<input type="submit" name="submit" value="Validate" />
</form>
</p>
</body>
</html>
TOPPAGE
  end

  def output
    $stdout.write <<EOF
Status: #{@resp[2] or '200 OK'}\r
Content-Type: #{@resp[0]}\r
Content-Length: #{@resp[1].size + 1}\r
\r
#{@resp[1]}
EOF
  end

  # SBCS/DBCS encoding level
  def validate1
    case @xml
    when /^\xFE\xFF\x00</ then
      @msgs.push 'Error: encoding UTF-16BE+BOM'
    when /^\xFF\xFE<\x00/ then
      # throw(:kill, 'Fatal: encoding UTF-16LE+BOM')
      @msgs.push 'Error: encoding UTF-16BE+BOM'
    when /^<\x00/ then
      @msgs.push 'Error: encoding UTF-16BE'
    when /^\x00</ then
      @msgs.push 'Error: encoding UTF-16LE'
    end
    @msgs.push @xml[0,16].inspect
  end

  def validate str
    @xml = str
    r = catch(:kill) {
      validate1
    }
    @msgs.push r if r
    @msgs.push 'no message' if @msgs.empty?
    e = @msgs.grep(/^[FE]/)
    keymsg = (e.empty? ? 'Validation success' : "Validation fails")
    @resp = ['text/html', <<VALIDATE]
<html>
<head><title>#{q keymsg}</title></head>
<body>
<h1>#{q keymsg}</h1>
<ul>
#{@msgs.map{|s| '<li>' + q(s) + '</li>'}}
</ul>
</body>
VALIDATE
  end

  def run
    begin
      if (f = @cgi.params['file'][0]) then
        validate f.read
      else
	toppage
      end
    rescue => e
      @resp = ['text/html', <<ERRORPAGE, '500 Internal Server Error']
<html>
<head><title>500 - #{q e.to_s}</title></head>
<body>
<h1>#{q e.to_s}</h1>
<h2>Backtrace</h2>
<ul>
#{e.backtrace.map{|s| '<li>' + q(s) + '</li>'}}
</ul>
</body>
ERRORPAGE
    end
    output
  end

  def q str
    str.nil? ? '(nil)' : CGI.escapeHTML(str.to_s)
  end

end

App.new.run
