// $Id: JGTrace.cpp,v 1.6 2003/03/16 14:51:01 fukasawa Exp $

//=============================================================================
/**
 *  @file    JGTrace.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2001-2003 BEE Co.,Ltd. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#include "JGTrace.h"
#include "JGTraceManager.h"
#include "JGVariable.h"
#include "JGTimeModule.h"
#include "BS2Message.h"
#include "BS2ListItem.h"
#include "BS2DeclAtoms.h"

extern void tv2string(BS2TimeValue& tv, string& retstr);

//-----------------------------------------------------------------------------
// Copy
//-----------------------------------------------------------------------------
JGTrace& JGTrace::operator=(const JGTrace& rhs)
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::operator=");
    if (this == &rhs)
        return *this;
    this->JGNameInfo::copy(rhs);
    m_dsper   = rhs.m_dsper;
    m_totsmp  = rhs.m_totsmp;
    m_repgsz  = rhs.m_repgsz;
    m_vars    = rhs.m_vars;
    m_manager = rhs.m_manager;
    return *this;
}

//-----------------------------------------------------------------------------
// Convert sampling time string to ACE_Time_Value.
//-----------------------------------------------------------------------------
void JGTrace::convertime()
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::convertime");

    long  msec;
    const BCHAR * timestr = m_dsper.c_str();
    BCHAR  hhbuf[8];
    BCHAR  mmbuf[8];
    BCHAR  ssbuf[8];

    hhbuf[0] = *(timestr + 0);
    hhbuf[1] = *(timestr + 1);
    hhbuf[2] = '\0';
    mmbuf[0] = *(timestr + 2);
    mmbuf[1] = *(timestr + 3);
    mmbuf[2] = '\0';
    ssbuf[0] = *(timestr + 4);
    ssbuf[1] = *(timestr + 5);
    ssbuf[2] = '\0';
    msec = 0;
    if (_tcslen(timestr) == 8)
    {   // Convert unit of 10 milli-seconds
        msec = _tcstoul(timestr + 6, NULL, 10) * 10;
    }
    msec += _tcstoul(ssbuf, NULL, 10) * 1000;         // seconds
    msec += _tcstoul(mmbuf, NULL, 10) * 1000 * 60;    // minutes
    msec += _tcstoul(hhbuf, NULL, 10) * 1000 * 3600;  // hours

    m_dspertv.msec(msec);

    return ;
}

//-----------------------------------------------------------------------------
// Sampling trace data.
//-----------------------------------------------------------------------------
void JGTrace::sampling()
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::sampling");

    JGVariables::iterator iter = m_vars.begin();
    for ( ; iter != m_vars.end(); ++iter)
    {
        JGVariable * var = *iter;
        m_values.push_back(var->getv());
    }

    return ;
}

//-----------------------------------------------------------------------------
// Create trace data.
//-----------------------------------------------------------------------------
BS2Message * JGTrace::create()
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::create");
    BS2ListItem * rootlist = new BS2ListItem();
    BS2Item * item;

    item = BS2Item::factory(_TX("TRID"), m_id);
    rootlist->add(item);

    item = BS2Item::factory(_TX("SMPLN"), new BS2UInt4(m_cursmp));
    rootlist->add(item);

    string smpltime;
    // tv2string(m_stime, smpltime);
    JGTimeModule::instance()->getDateAndTime(smpltime);
    item = BS2Item::factory(_TX("STIME"), new BS2Ascii(smpltime));
    rootlist->add(item);

    BS2ListItem * vlist = new BS2ListItem();
    BS2values::iterator iter = m_values.begin();
    for ( ; iter != m_values.end(); ++iter)
    {
        item = BS2Item::factory(_TX("SV"), (*iter));
        vlist->add(item);
    }
    rootlist->add(vlist);

    BS2Message * msg = BS2Message::factory(SFCODE(6,1));
    msg->add(rootlist);

    return msg;
}


//-----------------------------------------------------------------------------
// Trace period.
//-----------------------------------------------------------------------------
void JGTrace::handle_time_out(const ACE_Time_Value &tv, const void * arg)
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::handle_time_out");
    ACE_UNUSED_ARG(arg);

    BS2Message * msg;

    // Sampling
    sampling();
    m_cursmp++;                         // Update sample length
    m_stime = tv;                       // Update sample time

    // Check send trace data or not
    if ((m_cursmp % m_repgsz) == 0)
    {
        // Send sampled data
        if ((msg = create()) == NULL)
        {
            TRACE_ERROR((_TX("Can't create message. trid = %s \n"),
                         m_id.toString().c_str()));
            m_manager->cancel(m_id);   // Stop timer.
            m_manager->remove(m_id);
            return ;
        }
        m_manager->send(msg);  // *** S6F1 ***

        // Clear sampled data
        m_values.clear();
    }

    // Check trace end
    if ((int)m_cursmp >= m_totsmp)
    {    // Trace End: Send remain sampled data
        if (m_values.size() > 0)
        {
            if ((msg = create()) == NULL)
            {
                TRACE_ERROR((_TX("Can't create message. trid = %s \n"),
                             m_id.toString().c_str()));
            }
            else
            {   // send sampling data
                m_manager->send(msg);  // *** S6F1 ***
            }
        }
        m_manager->cancel(m_id);   // Stop timer & remove trace
    }
    return ;
}


//-----------------------------------------------------------------------------
// Print items of the trace
//-----------------------------------------------------------------------------
void JGTrace::printOn(string& buf, int mode)
{
    TRACE_FUNCTION(TRL_LOW, "JGTrace::printOn");
    ACE_UNUSED_ARG(mode);

    BCHAR numbuf[128];
    m_id.get(buf);
    buf += _TX(" ");
    buf += m_dsper;
    _stprintf(numbuf, _TX(" %d"), m_totsmp);
    buf += numbuf;
    _stprintf(numbuf, _TX(" %d"), m_repgsz);
    buf += numbuf;

    return ;
}

