/*
** This file is part of awisetoolbox.
** Copyright (C) 2008-2017 by Alan Wise (awisesoftware@gmail.com)
**
** 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 3 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, see <http://www.gnu.org/licenses/>.
*/


/**
*** \file updatenotifier.cpp
*** \brief updatenotifier.h implementation file.
*** \details Implementation file for updatenotifier.h.
**/


/** Identifier for updatenotifier.cpp. **/
#define   UPDATENOTIFIER_CPP


/****
*****
***** INCLUDES
*****
****/

#include  "updatenotifier.h"
#if       defined(DEBUG_UPDATENOTIFIER_CPP)
#if       !defined(USE_DEBUGLOG)
#define   USE_DEBUGLOG
#endif    /* !defined(USE_DEBUGLOG) */
#endif    /* defined(DEBUG_UPDATENOTIFIER_CPP) */
#include  "debuglog.h"
#include  "messagelog.h"

#include  <QNetworkAccessManager>
#include  <QTimer>
#include  <QNetworkRequest>
#include  <QNetworkReply>


/****
*****
***** DEFINES
*****
****/

/**
*** \brief Update timer.
*** \details Base time between checks for updates.
**/
#define   UPDATETIMER_RATE    (24*60*60*1000)   /* 1 day, in milliseconds */


/****
*****
***** DATA TYPES
*****
****/


/****
*****
***** PROTOTYPES
*****
****/


/****
*****
***** DATA
*****
****/


/****
*****
***** VARIABLES
*****
****/


/****
*****
***** FUNCTIONS
*****
****/

UPDATENOTIFIER_C::UPDATENOTIFIER_C(void)
{
  DEBUGLOG_Printf0("UPDATENOTIFIER_C::UPDATENOTIFIER_C()");
  DEBUGLOG_LogIn();

  /* Initialize members. */
  m_CheckingFlag=false;
  m_UpdateInterval=1;
  m_UpdateIntervalCounter=0;

  /* Network access. */
  m_pNetworkAccess=new QNetworkAccessManager;
  connect(m_pNetworkAccess,SIGNAL(finished(QNetworkReply*)),
      this,SLOT(DownloadCompleteSlot(QNetworkReply*)));

  /* Create and start the timer. */
  m_pTimer=new QTimer(this);
  connect(m_pTimer,SIGNAL(timeout()),this,SLOT(TimerTriggeredSlot()));
  m_pTimer->start(UPDATETIMER_RATE);

  DEBUGLOG_LogOut();
  return;
}

UPDATENOTIFIER_C::~UPDATENOTIFIER_C(void)
{
  DEBUGLOG_Printf0("UPDATENOTIFIER_C::~UPDATENOTIFIER_C()");
  DEBUGLOG_LogIn();

  if (m_pTimer!=NULL)
  {
    MESSAGELOG_Error("NULL pointer.");
    delete m_pTimer;
  }
  if (m_pNetworkAccess!=NULL)
  {
    MESSAGELOG_Error("NULL pointer.");
    delete m_pNetworkAccess;
  }

  DEBUGLOG_LogOut();
  return;
}

ERRORCODE_T UPDATENOTIFIER_C::SetCheckForUpdateInterval(int Interval)
{
  ERRORCODE_T ErrorCode;


  DEBUGLOG_Printf1("UPDATENOTIFIER_C::SetCheckForUpdateInterval(%d)",Interval);
  DEBUGLOG_LogIn();

  /* Parameter checking. */
  if (Interval<=0)
  {
    ErrorCode=ERRORCODE_INVALIDPARAMETER;
    MESSAGELOG_LogError(ErrorCode);
  }
  else
  {
    /* Save the Interval. */
    m_UpdateIntervalCounter=Interval;

    /* Force an immediate check. */
    CheckForUpdate();

    ErrorCode=ERRORCODE_SUCCESS;
  }

  DEBUGLOG_LogOut();
  return(ErrorCode);
}

void UPDATENOTIFIER_C::SetURL(QString URL)
{
  DEBUGLOG_Printf2("UPDATENOTIFIER_C::SetURL(%p(%s))",&URL,qPrintable(URL));
  DEBUGLOG_LogIn();

  /* Save the URL. */
  m_URL=URL;

  /* Force an immediate check. */
  CheckForUpdate();

  DEBUGLOG_LogOut();
  return;
}

void UPDATENOTIFIER_C::CheckForUpdate(void)
{
  DEBUGLOG_Printf0("UPDATENOTIFIER_C::CheckForUpdate()");
  DEBUGLOG_LogIn();

  /* Restart the timer. */
  m_pTimer->start(UPDATETIMER_RATE);

  /* Check immediately. */
  m_UpdateIntervalCounter=0;
  TimerTriggeredSlot();

  DEBUGLOG_LogOut();
  return;
}

void UPDATENOTIFIER_C::DownloadCompleteSlot(QNetworkReply *pReply)
{
  QVariant RedirectURL;
  QNetworkRequest Request;
  QByteArray Data;


  DEBUGLOG_Printf1("UPDATENOTIFIER_C::DownloadCompleteSlot(%p)",pReply);
  DEBUGLOG_LogIn();

  /* Being redirected? */
  RedirectURL=pReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
  if (RedirectURL!=QVariant())
  {
    Request.setUrl(RedirectURL.toString());
    Request.setRawHeader("User-Agent","Mozilla Firefox");
        // See other comment about user agent.
    m_pNetworkAccess->get(Request);
  }
  else
  {
    /* Read the data. */
    Data=pReply->readAll();
    if (Data==QByteArray())
      emit VersionSignal(QString());
    else
    {
      /* Convert the data to a string. */
      QString DataString(Data);

      /* Inform the user. */
      emit VersionSignal(DataString);
    }

    m_CheckingFlag=false;
  }

  pReply->deleteLater();

  DEBUGLOG_LogOut();
  return;
}

void UPDATENOTIFIER_C::TimerTriggeredSlot(void)
{
  QNetworkRequest Request;


  DEBUGLOG_Printf0("UPDATENOTIFIER_C::TimerTriggeredSlot()");
  DEBUGLOG_LogIn();

  if ( (m_URL.isEmpty()==false) && (m_CheckingFlag==false) &&
      (m_UpdateIntervalCounter<=0) )
  {
    m_CheckingFlag=true;

    /* Send the request. */
    Request.setUrl(m_URL);
    Request.setRawHeader("User-Agent","Mozilla Firefox");
        // QNetworkRequest seems to default to "Mozilla" for the user agent
        //   and sourceforge has implemented blocking for certain user agents.
    m_pNetworkAccess->get(Request);
  }

  /* Reset counter (if necessary). */
  if (m_UpdateIntervalCounter<=0)
    m_UpdateIntervalCounter=m_UpdateInterval;

  DEBUGLOG_LogOut();
  return;
}


#undef    UPDATENOTIFIER_CPP
