//  Generate an HTML table showing path decomposition  ---------------------------------//

//  Copyright Beman Dawes 2005.

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  See http://www.boost.org/libs/filesystem for documentation.

//  For purposes of generating the table, support both POSIX and Windows paths

#include "boost/filesystem.hpp"
#include <iostream>
#include <fstream>

using boost::filesystem::path;
using std::string;
using std::cout;

namespace
{
  std::ifstream infile;
  std::ofstream posix_outfile;
  std::ifstream posix_infile;
  std::ofstream outfile;

  bool posix;

  const string empty_string;

  struct column_base
  {
    virtual string heading() const = 0;
    virtual string cell_value( const path & p ) const = 0;
  };

  struct c0 : public column_base
  {
    string heading() const { return string("<code>string()</code>"); }
    string cell_value( const path & p ) const { return p.string(); }
  } o0;

    struct c1 : public column_base
  {
    string heading() const { return string("<code>generic_<br>string()</code>"); }
    string cell_value( const path & p ) const { return p.generic_string(); }
  } o1;

  struct c2 : public column_base
  {
    string heading() const { return string("Iteration<br>over<br>Elements"); }
    string cell_value( const path & p ) const
    {
      string s;
      for( path::iterator i(p.begin()); i != p.end(); ++i )
      {
        if ( i != p.begin() ) s += ',';
        s += (*i).string();
      }
      return s;
    }
  } o2;

  struct c3 : public column_base
  {
    string heading() const { return string("<code>root_<br>path()</code>"); }
    string cell_value( const path & p ) const { return p.root_path().string(); }
  } o3;

  struct c4 : public column_base
  {
    string heading() const { return string("<code>root_<br>name()</code>"); }
    string cell_value( const path & p ) const { return p.root_name().string(); }
  } o4;

  struct c5 : public column_base
  {
    string heading() const { return string("<code>root_<br>directory()</code>"); }
    string cell_value( const path & p ) const { return p.root_directory().string(); }
  } o5;

  struct c6 : public column_base
  {
    string heading() const { return string("<code>relative_<br>path()</code>"); }
    string cell_value( const path & p ) const { return p.relative_path().string(); }
  } o6;

  struct c7 : public column_base
  {
    string heading() const { return string("<code>parent_<br>path()</code>"); }
    string cell_value( const path & p ) const { return p.parent_path().string(); }
  } o7;

  struct c8 : public column_base
  {
    string heading() const { return string("<code>filename()</code>"); }
    string cell_value( const path & p ) const { return p.filename().string(); }
  } o8;

  const column_base * column[] = { &o2, &o0, &o1, &o3, &o4, &o5, &o6, &o7, &o8 };

  //  do_cell  ---------------------------------------------------------------//

  void do_cell( const string & test_case, int i )
  {
    string temp = column[i]->cell_value(path(test_case));
    string value;
    outfile << "<td>";
    if (temp.empty())
      value = "<font size=\"-1\"><i>empty</i></font>";
    else
     value = string("<code>") + temp + "</code>";

    if (posix)
      posix_outfile << value << '\n';
    else
    {
      std::getline(posix_infile, temp);
      if (value != temp) // POSIX and Windows differ
      {
        value.insert(0, "<br>");
        value.insert(0, temp);
        value.insert(0, "<span style=\"background-color: #CCFFCC\">");
        value += "</span>";
      }
      outfile << value;
    }
    outfile << "</td>\n";
  }

//  do_row  ------------------------------------------------------------------//

  void do_row( const string & test_case )
  {
    outfile << "<tr>\n";

    if (test_case.empty())
      outfile << "<td><font size=\"-1\"><i>empty</i></font></td>\n";
    else
      outfile << "<td><code>" << test_case << "</code></td>\n";
    
    for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i )
    {
      do_cell( test_case, i );
    }

    outfile << "</tr>\n";
  }

//  do_table  ----------------------------------------------------------------//

  void do_table()
  {
    outfile <<
      "<h1>Path Decomposition Table</h1>\n"
      "<p>Shaded entries indicate cases where <i>POSIX</i> and <i>Windows</i>\n"
      "implementations yield different results. The top value is the\n"
      "<i>POSIX</i> result and the bottom value is the <i>Windows</i> result.\n" 
      "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n"
      "<p>\n"
      ;

    // generate the column headings

    outfile << "<tr><td><b>Constructor<br>argument</b></td>\n";

    for ( int i = 0; i < sizeof(column)/sizeof(column_base&); ++i )
    {
      outfile << "<td><b>" << column[i]->heading() << "</b></td>\n";
    }

    outfile << "</tr>\n";

    // generate a row for each input line

    string test_case;
    while ( std::getline( infile, test_case ) )
    {
      if (!test_case.empty() && *--test_case.end() == '\r')
        test_case.erase(test_case.size()-1);
      if (test_case.empty() || test_case[0] != '#')
        do_row( test_case );
    }

    outfile << "</table>\n";
  }

} // unnamed namespace

//  main  ------------------------------------------------------------------------------//

#define BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE
#include <boost/test/included/prg_exec_monitor.hpp>

int cpp_main( int argc, char * argv[] ) // note name!
{
  if ( argc != 5 )
  {
    std::cerr <<
      "Usage: path_table \"POSIX\"|\"Windows\" input-file posix-file output-file\n"
      "Run on POSIX first, then on Windows\n"
      "  \"POSIX\" causes POSIX results to be save in posix-file;\n"
      "  \"Windows\" causes POSIX results read from posix-file\n"
      "  input-file contains the paths to appear in the table.\n"
      "  posix-file will be used for POSIX results\n"
      "  output-file will contain the generated HTML.\n"
      ;
    return 1;
  }

  infile.open( argv[2] );
  if ( !infile )
  {
    std::cerr << "Could not open input file: " << argv[2] << std::endl;
    return 1;
  }

  if (string(argv[1]) == "POSIX")
  {
    posix = true;
    posix_outfile.open( argv[3] );
    if ( !posix_outfile )
    {
      std::cerr << "Could not open POSIX output file: " << argv[3] << std::endl;
      return 1;
    }
  }
  else
  {
    posix = false;
    posix_infile.open( argv[3] );
    if ( !posix_infile )
    {
      std::cerr << "Could not open POSIX input file: " << argv[3] << std::endl;
      return 1;
    }
  }

  outfile.open( argv[4] );
  if ( !outfile )
  {
    std::cerr << "Could not open output file: " << argv[2] << std::endl;
    return 1;
  }

  outfile << "<html>\n"
          "<head>\n"
          "<title>Path Decomposition Table</title>\n"
          "</head>\n"
          "<body bgcolor=\"#ffffff\" text=\"#000000\">\n"
          ;

  do_table();

  outfile << "</body>\n"
          "</html>\n"
          ;

  return 0;
}
