/**
       Parses the configuration file. If the file does not exist this is ignored.
    */
    void ConfigurationFileParser::Parse()
    {
        SCXCoreLib::SCXLogHandle log = SCXLogHandleFactory::GetLogHandle(L"scx.core.providers.runasprovider.configparser");

        try
        {
            ParseStream(*SCXFile::OpenWFstream(m_file, std::ios_base::in));
        }
        catch (SCXException& e)
        {
            SCX_LOGWARNING(log, StrAppend(L"Failed to read file: ", m_file.Get()));
            SCX_LOGWARNING(log, StrAppend(L"Reason for failure: ", e.What()));
        }
    }
    /**
    Gather the Major and Minor version from Product version

    Parameters:  version - Product version, its format like 11.23.32, REV- or 0.4b41

    */
    void InstalledSoftwareInstance::SetDetailedVersion(const wstring& version)
    {
        size_t pos = version.find_first_of('.');
        if( pos != wstring::npos )
        {
            wstring left = version.substr(0, pos);
            wstring right = version.substr(pos+1);
            try
            {
                m_versionMajor = StrToUInt(left);
                // Exclude characters
                for(pos = 0; pos< right.size(); pos++)
                {
                    if( right[pos] < '0' || right[pos] > '9' ) {
                        break;
                    }
                }
                if(pos > 0) {
                    left = right.substr(0, pos);
                    m_versionMinor = StrToUInt(left);
                }
            }
            catch (const SCXException& e)
            {
                SCX_LOGWARNING(m_log, StrAppend(L"parse InstalledSoftwareInstance version fails:", version).append(L" - ").append(e.What()));
            }
        }
    }
    /**
    Translate install date from string to SCXCalendarTime

    Parameters:  installDate - its format like Aug 04 2010 10:24

    */
    void InstalledSoftwareInstance::SetInstallDate(const wstring& installDate)
    {
        tm          installtm;
        const std::string nsInstallDate = StrToMultibyte(installDate);
        const char *buf      = nsInstallDate.c_str();
        size_t      ccLength = installDate.length();
        const char *bufend   = buf + ccLength;
        const char *format   = "%b %d %Y %H:%M";
        const char *ret      = strptime(buf, format, &installtm);

        if (ret == bufend)
        {
            SCXCoreLib::SCXCalendarTime instDate((scxyear)(installtm.tm_year + 1900), (scxmonth)(installtm.tm_mon + 1), (scxday)(installtm.tm_mday));
            instDate.SetHour((scxhour)(installtm.tm_hour));
            instDate.SetMinute((scxminute)(installtm.tm_min));
            m_installDate = instDate;
        }
        else
        {
            SCX_LOGWARNING(m_log, StrAppend(L"strptime installDate fails: ", installDate));
            m_installDate = SCXCalendarTime::FromPosixTime(0);
        }
    }
    /**
    Translate install date from string to SCXCalendarTime

    Parameters:  installDate - 
                 INDEX calendar dates are unlike CIM DATE or other common forms.
                 INDEX calendar date format: YYYYMMDDhhmm.ss
                 Example INDEX entry: install_date 201101021654.08

    */
    void InstalledSoftwareInstance::SetInstallDate(const wstring& installDate)
    {

        try
        {
            unsigned int year = SCXCoreLib::StrToUInt(installDate.substr(0, 4));
            unsigned int month = SCXCoreLib::StrToUInt(installDate.substr(4, 2));
            unsigned int day = SCXCoreLib::StrToUInt(installDate.substr(6, 2));
            unsigned int hour = SCXCoreLib::StrToUInt(installDate.substr(8, 2));
            unsigned int minute = SCXCoreLib::StrToUInt(installDate.substr(10, 2));
            // Char at position 12 is '.'
            unsigned int second = SCXCoreLib::StrToUInt(installDate.substr(13, 2));

            SCXCalendarTime scxctInstall(year, month, day);
            scxctInstall.SetHour(hour);
            scxctInstall.SetMinute(minute);
            scxctInstall.SetSecond(second);
            m_installDate = scxctInstall;
        }
        catch(SCXException& e)
        {
            SCX_LOGWARNING(m_log, L"Bad INDEX install_date: " + installDate + L" " + e.What() + e.Where());
        }
    }
    /**
       Helper method for reading instances from disk
       
       \param[in] preader - handle to the physical media reader
       \param[out] instances - vector of Application Server Instances 
                               to insert the values read from disk into 

    */
    bool PersistAppServerInstances::ReadFromDiskHelper(
            SCXHandle<SCXPersistDataReader>& preader,
            vector<SCXHandle<AppServerInstance> >& instances)
    {
        
        bool isThereAnElement = preader->ConsumeStartGroup(APP_SERVER_INSTANCE, false);
        
        if (isThereAnElement)
        {
            wstring id, diskPath, httpPort, httpsPort, protocol, isDeepMonitored, type, version, profile, cell, node, server;
            diskPath = preader->ConsumeValue(APP_SERVER_DISK_PATH);
            try
            {
                id = preader->ConsumeValue(APP_SERVER_ID);
            }
            catch(PersistUnexpectedDataException)
            {
                // To be backward compatible, we default to disk path if id is not in the persited data
                id = diskPath;
                SCX_LOGTRACE(m_log, L"Id not found in persited data, defaulting to disk path");
            }
            httpPort = preader->ConsumeValue(APP_SERVER_HTTP_PORT);
            httpsPort = preader->ConsumeValue(APP_SERVER_HTTPS_PORT);
            try
            {
                protocol = preader->ConsumeValue(APP_SERVER_PROTOCOL);
            }
            catch(PersistUnexpectedDataException)
            {
                // To be backward compatible, we default to HTTP if protocol is not in the persited data
                protocol = PROTOCOL_HTTP;
                SCX_LOGTRACE(m_log, L"Protocol not found in persited data, defaulting to HTTP");
            }
            isDeepMonitored = preader->ConsumeValue(APP_SERVER_IS_DEEP_MONITORED);
            type = preader->ConsumeValue(APP_SERVER_TYPE);
            version = preader->ConsumeValue(APP_SERVER_VERSION);
            try
            {
                profile = preader->ConsumeValue(APP_SERVER_PROFILE);
                cell = preader->ConsumeValue(APP_SERVER_CELL);
                node = preader->ConsumeValue(APP_SERVER_NODE);
                server = preader->ConsumeValue(APP_SERVER_SERVER);
            }
            catch(PersistUnexpectedDataException)
            {
                // To be backward compatible, we default profile, cell, node & server to 
                // empty strings if they are not in the persited data
                profile = L"";
                cell = L"";
                node = L"";
                server = L"";
                SCX_LOGTRACE(m_log, L"WebSphere properties not found in persited data, defaulting to empty strings");
            }
            preader->ConsumeEndGroup(true);

            SCXHandle<AppServerInstance> instance;

            bool badType = false;

            if (APP_SERVER_TYPE_JBOSS == type)
            {
                instance = new  JBossAppServerInstance(diskPath);
            } 
            else if (APP_SERVER_TYPE_TOMCAT == type)
            {
                instance = new  TomcatAppServerInstance(diskPath, diskPath);
            }
            else if (APP_SERVER_TYPE_WEBLOGIC == type)
            {
                instance = new  WebLogicAppServerInstance(diskPath);
                instance->SetServer(server);
            }
            else if (APP_SERVER_TYPE_WEBSPHERE == type)
            {
                instance = new  WebSphereAppServerInstance(diskPath, cell, node, profile, server);
            }
            else
            {
                SCX_LOGWARNING(m_log, wstring(L"Unknown application server type read from cache: ").append(type));
                badType = true;
            }

            if (!badType)
            {
                instance->SetHttpPort(httpPort);
                instance->SetHttpsPort(httpsPort);
            
                // This value is a bool, but when written to disk it is 
                // serialized as an integer.
                instance->SetIsDeepMonitored(L"1" == isDeepMonitored, protocol);
            
                // If read from cache, then by default this representation
                // of the instance is not running
                instance->SetIsRunning(false);
                instance->SetVersion(version);
                instances.push_back(instance);
            }
        }
        
        return isThereAnElement;
    }