//<copyright>
//
// Copyright (c) 1997
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
//
//</copyright>

//<file>
//
// Name:    dependon.C
//
// Purpose: dependencies from other binaries
//
// Created: 21 Jan 1997 Till Vollmer
//
// $Id: dependon.C,v 1.5 1997/03/03 11:39:17 jfasch Exp $
//
// Description:
//   
//</file>
//
// $Log: dependon.C,v $
// Revision 1.5  1997/03/03 11:39:17  jfasch
// use HGWhat instead of hardcoding it
//
// Revision 1.4  1997/03/03 11:28:20  tvollmer
// ntr.h moved to utils
//
// Revision 1.3  1997/02/10 14:41:03  gorasche
// changes for Win32
//
// Revision 1.2  1997/01/30 18:45:20  tvollmer
// bug removed plose
//
// Revision 1.1  1997/01/22 13:13:07  tvollmer
// Initial revision
//
//

#include "dependon.h"
#include "hgwhat.h"
#include <hyperg/utils/assert.h>
#include <stdio.h>
#include <hyperg/utils/nstr.h>
#include <hyperg/utils/hgregexp.h>

#ifdef WIN32
#define popen _popen
#define pclose _pclose
#endif

DependVersion::DependVersion(const RString& ver)
{
    NString major;
    NString minor;
    int pos=0;
    ver.gWordChar(pos,'.',major);
    minor  = ver.gRight(pos+1);
    major_ = major.toInt() ;
    minor_ = minor.toInt() ;
}


bool DependVersion::operator ==( const DependVersion& it) const
{
    return (*this).minor_ == it.minor_ && (*this).major_ == it.major_ ; 
}

bool DependVersion::operator < ( const DependVersion& it) const
{
    if ((*this).major_ < it.major_)
        return true;
    else
        if ((*this).major_ == it.major_)
        {
            if ((*this).minor_ < it.minor_)
                return true ;
            
        }
    return false;
}

DependVersion::operator RString() const
{
    NString minor;
    minor.loadLong(minor_,"%02d") ;
    NString major;
    major.loadLong(major_) ;
    return major+ "." + minor ;
}



bool DependAND :: evaluate(RStringField& reason) const
{
    hgassert(atom1_.ok() && atom2_.ok(),"DependAND::evaluate() atoms not proper initialized") ;
    bool a1 =  atom1_.ptr()->evaluate(reason);
    bool a2 =  atom2_.ptr()->evaluate(reason);   // to prevent 
    return a1 && a2 ;
}
bool DependOR :: evaluate(RStringField& reason) const
{
    hgassert(atom1_.ok() && atom2_.ok(),"DependOR::evaluate() atoms not proper initialized") ;
    bool a1 =  atom1_.ptr()->evaluate(reason);
    bool a2 =  atom2_.ptr()->evaluate(reason);   // to prevent 
    return a1 || a2 ;
}

// bool DependEntry :: evaluate(RStringField& reason) const
// {
//     char buf[256];
//     FILE* subproc =  ::popen(command_ + " -version","r") ;
//     if (subproc)
//     {
//         size_t charsread = fread(buf,1,256,subproc);
//         RString info(buf,charsread);
//         // now check the result for hgregexp
//         static HgRegexp reg_info = "@\\(#\\)\\[(Hyper-G|HyperWave)\\][ \t]+" // base
//                               "\\[([-A-Za-z_]+)\\]" // type
//                               "[ \t]+"
//                               "([-A-Za-z_\\(\\)\\.]+)" // name
//                               "[ \t]+"
//                               "([0-9]+\\.[0-9]+)" // version
//                               "([ A-Za-z0-9\\.\t]*)" // additional
//                               "[ \t]+\\[([-&,;A-Za-z0-9_ \t\\./]+)\\]" // description
//                               "[ \t]+"
//                               "\\[([-@&,;A-Za-z0-9_ \t\\./]+)\\]"; // author
//         NString version;
     
//      // @ (#)[Hyper-G] [HGS-LS] hgserver  1.44 [server module] [Gerald Pani]
//      // @ (#)[HyperWave] [HGS-LS] hgserver  1.44 [server module] [Gerald Pani]
        
//         ::pclose(subproc) ;
//         if (reg_info.Match( info, info.length(), 0) > 0) 
//         {
// //            base = info.gSubstrIndex( reg_info.BeginningOfMatch(1), reg_info.EndOfMatch(1) -1);
// //            type = info.gSubstrIndex( reg_info.BeginningOfMatch(2), reg_info.EndOfMatch(2) -1);
// //            name = info.gSubstrIndex( reg_info.BeginningOfMatch(3), reg_info.EndOfMatch(3) -1);
//             DependVersion version = DependVersion (info.gSubstrIndex( reg_info.BeginningOfMatch(4), reg_info.EndOfMatch(4) -1)) ;
// //            additional = info.gSubstrIndex( reg_info.BeginningOfMatch(5), reg_info.EndOfMatch(5) -1);
// //            descr = info.gSubstrIndex( reg_info.BeginningOfMatch(6), reg_info.EndOfMatch(6) -1);
// //            author = info.gSubstrIndex( reg_info.BeginningOfMatch(7), reg_info.EndOfMatch(7) -1);
//             switch (op_)
//             {
//                 case EQUAL:
//                     if (version == version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" MUST have version " + version_ + "but has version "+ version);  
//                         return false ;
//                     }
//                 break;
//                 case NOT_EQUAL:
//                     if (version != version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" is NOT allowed to have version " + version_);  
//                         return false ;
//                     }
                    
//                 break ;
//                 case LESS:
//                     if (version < version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version less than " + version_ + " but has version "+ version);  
//                         return false ;
//                     }

//                 break;
//                 case LESS_EQUAL:
//                     if (version <= version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version less or equal than " + version_ + " but has version "+ version);  
//                         return false ;
//                     }
//                 break ;
//                 case GREATER:
//                     if (version > version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version greater than " + version_ + " but has version "+ version);  
//                         return false ;
//                     }
//                 break;
//                 case GREATER_EQUAL:
//                     if (version >= version_) 
//                         return true;
//                     else
//                     {
//                         reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version greater or equal than " + version_ + " but has version "+ version);  
//                         return false ;
//                     }
//                 break;
//                 default:
//                     hgassert(0,"DependEntry::evaluate()") ;
//                     return false;  // satisfy compiler
//                 break;
//             }
            
            
//         }
//         else
//         {
//             reason.append("* (DependOn) Command \"" + command_ + "\" returned no proper version string.");
//             return false;
//         }
        
//     }
//     else
//     {
//         reason.append("* (DependOn) Could not find \"" + command_ + "\" for version checking.");
//         return false;
//     }
// }
bool DependEntry :: evaluate(RStringField& reason) const
{
    char buf[256];
    FILE* subproc =  ::popen(command_ + " -version","r") ;
    if (subproc)
    {
        size_t charsread = fread(buf,1,256,subproc);
        RString info(buf,charsread);
        ::pclose(subproc) ;
        HGWhat whatstr(info) ;
        if (whatstr.ok()) 
        {
            DependVersion version = DependVersion (whatstr.version()) ;
            switch (op_)
            {
                case EQUAL:
                    if (version == version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" MUST have version " + version_ + "but has version "+ version);  
                        return false ;
                    }
                break;
                case NOT_EQUAL:
                    if (version != version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" is NOT allowed to have version " + version_);  
                        return false ;
                    }
                    
                break ;
                case LESS:
                    if (version < version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version less than " + version_ + " but has version "+ version);  
                        return false ;
                    }

                break;
                case LESS_EQUAL:
                    if (version <= version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version less or equal than " + version_ + " but has version "+ version);  
                        return false ;
                    }
                break ;
                case GREATER:
                    if (version > version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version greater than " + version_ + " but has version "+ version);  
                        return false ;
                    }
                break;
                case GREATER_EQUAL:
                    if (version >= version_) 
                        return true;
                    else
                    {
                        reason.append("* (DependOn) Command \"" + command_ + "\" MUST have a version greater or equal than " + version_ + " but has version "+ version);  
                        return false ;
                    }
                break;
                default:
                    hgassert(0,"DependEntry::evaluate()") ;
                    return false;  // satisfy compiler
                break;
            }
            
            
        }
        else
        {
            reason.append("* (DependOn) Command \"" + command_ + "\" returned no proper version string.");
            return false;
        }
        
    }
    else
    {
        reason.append("* (DependOn) Could not find \"" + command_ + "\" for version checking.");
        return false;
    }
}
