// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC
#include "jsontest.h"
#include <stdio.h>
#include <string>

#if defined(_MSC_VER)
// Used to install a report hook that prevent dialog on assertion and error.
# include <crtdbg.h>
#endif // if defined(_MSC_VER)

#if defined(_WIN32)
// Used to prevent dialog on memory fault.
// Limits headers included by Windows.h
# define WIN32_LEAN_AND_MEAN
# define NOSERVICE
# define NOMCX
# define NOIME
# define NOSOUND
# define NOCOMM
# define NORPC
# define NOGDI
# define NOUSER
# define NODRIVERS
# define NOLOGERROR
# define NOPROFILER
# define NOMEMMGR
# define NOLFILEIO
# define NOOPENFILE
# define NORESOURCE
# define NOATOM
# define NOLANGUAGE
# define NOLSTRING
# define NODBCS
# define NOKEYBOARDINFO
# define NOGDICAPMASKS
# define NOCOLOR
# define NOGDIOBJ
# define NODRAWTEXT
# define NOTEXTMETRIC
# define NOSCALABLEFONT
# define NOBITMAP
# define NORASTEROPS
# define NOMETAFILE
# define NOSYSMETRICS
# define NOSYSTEMPARAMSINFO
# define NOMSG
# define NOWINSTYLES
# define NOWINOFFSETS
# define NOSHOWWINDOW
# define NODEFERWINDOWPOS
# define NOVIRTUALKEYCODES
# define NOKEYSTATES
# define NOWH
# define NOMENUS
# define NOSCROLL
# define NOCLIPBOARD
# define NOICONS
# define NOMB
# define NOSYSCOMMANDS
# define NOMDI
# define NOCTLMGR
# define NOWINMESSAGES
# include <windows.h>
#endif // if defined(_WIN32)

namespace JsonTest {


// class TestResult
// //////////////////////////////////////////////////////////////////

TestResult::TestResult()
   : predicateId_( 1 )
   , lastUsedPredicateId_( 0 )
   , messageTarget_( 0 )
{
   // The root predicate has id 0
   rootPredicateNode_.id_ = 0;
   rootPredicateNode_.next_ = 0;
   predicateStackTail_ = &rootPredicateNode_;
}


void 
TestResult::setTestName( const std::string &name )
{
   name_ = name;
}

TestResult &
TestResult::addFailure( const char *file, unsigned int line,
                        const char *expr )
{
   /// Walks the PredicateContext stack adding them to failures_ if not already added.
   unsigned int nestingLevel = 0;
   PredicateContext *lastNode = rootPredicateNode_.next_;
   for ( ; lastNode != 0; lastNode = lastNode->next_ )
   {
      if ( lastNode->id_ > lastUsedPredicateId_ ) // new PredicateContext
      {
         lastUsedPredicateId_ = lastNode->id_;
         addFailureInfo( lastNode->file_, lastNode->line_, lastNode->expr_,
                         nestingLevel );
         // Link the PredicateContext to the failure for message target when 
         // popping the PredicateContext.
         lastNode->failure_ = &( failures_.back() );
      }
      ++nestingLevel;
   }

   // Adds the failed assertion
   addFailureInfo( file, line, expr, nestingLevel );
   messageTarget_ = &( failures_.back() );
   return *this;
}


void 
TestResult::addFailureInfo( const char *file, unsigned int line,
                            const char *expr, unsigned int nestingLevel )
{
   Failure failure;
   failure.file_ = file;
   failure.line_ = line;
   if ( expr )
   {
      failure.expr_ = expr;
   }
   failure.nestingLevel_ = nestingLevel;
   failures_.push_back( failure );
}


TestResult &
TestResult::popPredicateContext()
{
   PredicateContext *lastNode = &rootPredicateNode_;
   while ( lastNode->next_ != 0  &&  lastNode->next_->next_ != 0 )
   {
      lastNode = lastNode->next_;
   }
   // Set message target to popped failure
   PredicateContext *tail = lastNode->next_;
   if ( tail != 0  &&  tail->failure_ != 0 )
   {
      messageTarget_ = tail->failure_;
   }
   // Remove tail from list
   predicateStackTail_ = lastNode;
   lastNode->next_ = 0;
   return *this;
}


bool 
TestResult::failed() const
{
   return !failures_.empty();
}


unsigned int 
TestResult::getAssertionNestingLevel() const
{
   unsigned int level = 0;
   const PredicateContext *lastNode = &rootPredicateNode_;
   while ( lastNode->next_ != 0 )
   {
      lastNode = lastNode->next_;
      ++level;
   }
   return level;
}


void 
TestResult::printFailure( bool printTestName ) const
{
   if ( failures_.empty() )
   {
      return;
   }

   if ( printTestName )
   {
      printf( "* Detail of %s test failure:\n", name_.c_str() );
   }

   // Print in reverse to display the callstack in the right order
   Failures::const_iterator itEnd = failures_.end();
   for ( Failures::const_iterator it = failures_.begin(); it != itEnd; ++it )
   {
      const Failure &failure = *it;
      std::string indent( failure.nestingLevel_ * 2, ' ' );
      if ( failure.file_ )
      {
         printf( "%s%s(%d): ", indent.c_str(), failure.file_, failure.line_ );
      }
      if ( !failure.expr_.empty() )
      {
         printf( "%s\n", failure.expr_.c_str() );
      }
      else if ( failure.file_ )
      {
         printf( "\n" );
      }
      if ( !failure.message_.empty() )
      {
         std::string reindented = indentText( failure.message_, indent + "  " );
         printf( "%s\n", reindented.c_str() );
      }
   }
}


std::string 
TestResult::indentText( const std::string &text, 
                        const std::string &indent )
{
   std::string reindented;
   std::string::size_type lastIndex = 0;
   while ( lastIndex < text.size() )
   {
      std::string::size_type nextIndex = text.find( '\n', lastIndex );
      if ( nextIndex == std::string::npos )
      {
         nextIndex = text.size() - 1;
      }
      reindented += indent;
      reindented += text.substr( lastIndex, nextIndex - lastIndex + 1 );
      lastIndex = nextIndex + 1;
   }
   return reindented;
}


TestResult &
TestResult::addToLastFailure( const std::string &message )
{
   if ( messageTarget_ != 0 )
   {
      messageTarget_->message_ += message;
   }
   return *this;
}

TestResult &
TestResult::operator << ( Json::Int64 value ) {
   return addToLastFailure( Json::valueToString(value) );
}


TestResult &
TestResult::operator << ( Json::UInt64 value ) {
   return addToLastFailure( Json::valueToString(value) );
}


TestResult &
TestResult::operator << ( bool value ) {
   return addToLastFailure(value ? "true" : "false");
}


// class TestCase
// //////////////////////////////////////////////////////////////////

TestCase::TestCase()
   : result_( 0 )
{
}


TestCase::~TestCase()
{
}


void 
TestCase::run( TestResult &result )
{
   result_ = &result;
   runTestCase();
}



// class Runner
// //////////////////////////////////////////////////////////////////

Runner::Runner()
{
}


Runner &
Runner::add( TestCaseFactory factory )
{
   tests_.push_back( factory );
   return *this;
}


unsigned int 
Runner::testCount() const
{
   return static_cast<unsigned int>( tests_.size() );
}


std::string 
Runner::testNameAt( unsigned int index ) const
{
   TestCase *test = tests_[index]();
   std::string name = test->testName();
   delete test;
   return name;
}


void 
Runner::runTestAt( unsigned int index, TestResult &result ) const
{
   TestCase *test = tests_[index]();
   result.setTestName( test->testName() );
   printf( "Testing %s: ", test->testName() );
   fflush( stdout );
#if JSON_USE_EXCEPTION
   try 
   {
#endif // if JSON_USE_EXCEPTION
      test->run( result );
#if JSON_USE_EXCEPTION
   } 
   catch ( const std::exception &e ) 
   {
      result.addFailure( __FILE__, __LINE__, 
         "Unexpected exception caught:" ) << e.what();
   }
#endif // if JSON_USE_EXCEPTION
   delete test;
   const char *status = result.failed() ? "FAILED" 
                                        : "OK";
   printf( "%s\n", status );
   fflush( stdout );
}


bool 
Runner::runAllTest( bool printSummary ) const
{
   unsigned int count = testCount();
   std::deque<TestResult> failures;
   for ( unsigned int index = 0; index < count; ++index )
   {
      TestResult result;
      runTestAt( index, result );
      if ( result.failed() )
      {
         failures.push_back( result );
      }
   }

   if ( failures.empty() )
   {
      if ( printSummary )
      {
         printf( "All %d tests passed\n", count );
      }
      return true;
   }
   else
   {
      for ( unsigned int index = 0; index < failures.size(); ++index )
      {
         TestResult &result = failures[index];
         result.printFailure( count > 1 );
      }

      if ( printSummary )
      {
         unsigned int failedCount = static_cast<unsigned int>( failures.size() );
         unsigned int passedCount = count - failedCount;
         printf( "%d/%d tests passed (%d failure(s))\n", passedCount, count, failedCount );
      }
      return false;
   }
}


bool 
Runner::testIndex( const std::string &testName, 
                   unsigned int &indexOut ) const
{
   unsigned int count = testCount();
   for ( unsigned int index = 0; index < count; ++index )
   {
      if ( testNameAt(index) == testName )
      {
         indexOut = index;
         return true;
      }
   }
   return false;
}


void 
Runner::listTests() const
{
   unsigned int count = testCount();
   for ( unsigned int index = 0; index < count; ++index )
   {
      printf( "%s\n", testNameAt( index ).c_str() );
   }
}


int 
Runner::runCommandLine( int argc, const char *argv[] ) const
{
   typedef std::deque<std::string> TestNames;
   Runner subrunner;
   for ( int index = 1; index < argc; ++index )
   {
      std::string opt = argv[index];
      if ( opt == "--list-tests" )
      {
         listTests();
         return 0;
      }
      else if ( opt == "--test-auto" )
      {
         preventDialogOnCrash();
      }
      else if ( opt == "--test" )
      {
         ++index;
         if ( index < argc )
         {
            unsigned int testNameIndex;
            if ( testIndex( argv[index], testNameIndex ) )
            {
               subrunner.add( tests_[testNameIndex] );
            }
            else
            {
               fprintf( stderr, "Test '%s' does not exist!\n", argv[index] );
               return 2;
            }
         }
         else
         {
            printUsage( argv[0] );
            return 2;
         }
      }
      else
      {
         printUsage( argv[0] );
         return 2;
      }
   }
   bool succeeded;
   if ( subrunner.testCount() > 0 )
   {
      succeeded = subrunner.runAllTest( subrunner.testCount() > 1 );
   }
   else
   {
      succeeded = runAllTest( true );
   }
   return succeeded ? 0 
                    : 1;
}


#if defined(_MSC_VER)
// Hook MSVCRT assertions to prevent dialog from appearing
static int 
msvcrtSilentReportHook( int reportType, char *message, int *returnValue )
{
   // The default CRT handling of error and assertion is to display
   // an error dialog to the user.
   // Instead, when an error or an assertion occurs, we force the 
   // application to terminate using abort() after display
   // the message on stderr. 
   if ( reportType == _CRT_ERROR  ||  
        reportType == _CRT_ASSERT )
   {
      // calling abort() cause the ReportHook to be called
      // The following is used to detect this case and let's the
      // error handler fallback on its default behaviour (
      // display a warning message)
      static volatile bool isAborting = false;
      if ( isAborting ) 
      {
         return TRUE;
      }
      isAborting = true;

      fprintf( stderr, "CRT Error/Assert:\n%s\n", message );
      fflush( stderr );
      abort();
   }
   // Let's other reportType (_CRT_WARNING) be handled as they would by default
   return FALSE;
}
#endif // if defined(_MSC_VER)


void 
Runner::preventDialogOnCrash()
{
#if defined(_MSC_VER)
   // Install a hook to prevent MSVCRT error and assertion from
   // popping a dialog.
   _CrtSetReportHook( &msvcrtSilentReportHook );
#endif // if defined(_MSC_VER)

   // @todo investiguate this handler (for buffer overflow)
   // _set_security_error_handler

#if defined(_WIN32)
   // Prevents the system from popping a dialog for debugging if the
   // application fails due to invalid memory access.
   SetErrorMode( SEM_FAILCRITICALERRORS 
                 | SEM_NOGPFAULTERRORBOX 
                 | SEM_NOOPENFILEERRORBOX );
#endif // if defined(_WIN32)
}

void 
Runner::printUsage( const char *appName )
{
   printf( 
      "Usage: %s [options]\n"
      "\n"
      "If --test is not specified, then all the test cases be run.\n"
      "\n"
      "Valid options:\n"
      "--list-tests: print the name of all test cases on the standard\n"
      "              output and exit.\n"
      "--test TESTNAME: executes the test case with the specified name.\n"
      "                 May be repeated.\n"
      "--test-auto: prevent dialog prompting for debugging on crash.\n"
      , appName );
}



// Assertion functions
// //////////////////////////////////////////////////////////////////

TestResult &
checkStringEqual( TestResult &result, 
                  const std::string &expected, const std::string &actual,
                  const char *file, unsigned int line, const char *expr )
{
   if ( expected != actual )
   {
      result.addFailure( file, line, expr );
      result << "Expected: '" << expected << "'\n";
      result << "Actual  : '" << actual << "'";
   }
   return result;
}


} // namespace JsonTest
