/*
  Copyright (c) 2012 Montel Laurent <montel@kde.org>
  
  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License, version 2, as
  published by the Free Software Foundation.
  
  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.,
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "operasettings.h"

#include "mailimporter/filter_opera.h"

#include <mailtransport/transportmanager.h>
#include "mailcommon/mailutil.h"

#include <kpimidentities/identity.h>
#include <kpimidentities/signature.h>


#include <KConfig>
#include <KConfigGroup>
#include <QFile>

OperaSettings::OperaSettings(const QString &filename, ImportWizard *parent)
  :AbstractSettings( parent )
{
  if(QFile( filename ).exists()) {
    KConfig config( filename );
    KConfigGroup grp = config.group(QLatin1String("Accounts"));
    readGlobalAccount(grp);
    const QStringList accountList = config.groupList().filter( QRegExp( "Account\\d+" ) );
    const QStringList::const_iterator end( accountList.constEnd() );
    for ( QStringList::const_iterator it = accountList.constBegin(); it!=end; ++it )
    {
      KConfigGroup group = config.group( *it );
      readAccount( group );
      readTransport(group);
      readIdentity(group);
    }
  }
}

OperaSettings::~OperaSettings()
{

}

void OperaSettings::readAccount(const KConfigGroup &grp)
{
  const QString incomingProtocol = grp.readEntry(QLatin1String("Incoming Protocol"));
  const int port = grp.readEntry(QLatin1String("Incoming Port"), -1);

  const QString serverName = grp.readEntry(QLatin1String("Incoming Servername"));
  const QString userName = grp.readEntry(QLatin1String("Incoming Username"));

  const int secure = grp.readEntry(QLatin1String("Secure Connection In"),-1);


  const int pollInterval = grp.readEntry(QLatin1String("Poll Interval"),-1);

  const int authMethod = grp.readEntry(QLatin1String("Incoming Authentication Method"),-1);

  const QString name = grp.readEntry(QLatin1String("Account Name"));

  const bool enableManualCheck = (grp.readEntry(QLatin1String("Manual Check Enabled"),0) == 1);

  //TODO
  const bool markAsSeen = (grp.readEntry(QLatin1String("Mark Read If Seen"),0) == 1);

  QMap<QString, QVariant> settings;
  if(incomingProtocol == QLatin1String("IMAP")) {
      settings.insert(QLatin1String("ImapServer"),serverName);
      settings.insert(QLatin1String("UserName"),userName);
      if ( port != -1 ) {
        settings.insert( QLatin1String( "ImapPort" ), port );
      }
      if(secure == 1) {
        settings.insert( QLatin1String( "Safety" ), QLatin1String("STARTTLS") );
      } else if( secure == 0) {
        settings.insert( QLatin1String( "Safety" ), QLatin1String("None") );
      }

      if(pollInterval == 0) {
        settings.insert(QLatin1String("IntervalCheckEnabled"), false);
      } else {
        settings.insert(QLatin1String("IntervalCheckEnabled"), true);
        settings.insert(QLatin1String("IntervalCheckTime"),pollInterval);
      }

      const QString agentIdentifyName = AbstractBase::createResource( "akonadi_imap_resource", name,settings );
      addToManualCheck(agentIdentifyName,enableManualCheck);
      //We have not settings for it => same than manual check
      addCheckMailOnStartup(agentIdentifyName,enableManualCheck);
  } else if(incomingProtocol == QLatin1String("POP")) {
      settings.insert( QLatin1String( "Host" ), serverName );
      settings.insert( QLatin1String( "Login" ), userName );

      const int leaveOnServer = grp.readEntry(QLatin1String("Leave On Server"),-1);
      if(leaveOnServer == 1) {
        settings.insert(QLatin1String("LeaveOnServer"),true);
      } else if(leaveOnServer == 0) {
        settings.insert(QLatin1String("LeaveOnServer"),false);
      } else {
        qDebug()<<" leave on server option unknown : "<<leaveOnServer;
      }

      const int removeMailFromSever = grp.readEntry(QLatin1String("Remove From Server Delay Enabled"),-1);
      if(removeMailFromSever == 1) {
          int removeDelay = grp.readEntry(QLatin1String("Remove From Server Delay"),-1);
          if(removeDelay!=-1) {
            //Opera store delay as second !!! :)
            removeDelay = removeDelay / (24*60*60);
            settings.insert(QLatin1String("LeaveOnServerDays"),removeDelay);
          }
      } //TODO: else

      if ( port != -1 ) {
        settings.insert( QLatin1String( "Port" ), port );
      }
      //TODO:
      const int delay = grp.readEntry(QLatin1String("Initial Poll Delay"),-1);

      if(pollInterval == 0) {
        settings.insert(QLatin1String("IntervalCheckEnabled"), false);
      } else {
        settings.insert(QLatin1String("IntervalCheckEnabled"), true);
        settings.insert(QLatin1String("IntervalCheckInterval"),pollInterval);
      }


      if(secure == 1)
        settings.insert( QLatin1String( "UseTLS" ), true );

      switch(authMethod) {
      case 0: //NONE
        settings.insert(QLatin1String( "AuthenticationMethod" ), MailTransport::Transport::EnumAuthenticationType::ANONYMOUS);
        break;
      case 1: //Clear Text
        settings.insert(QLatin1String( "AuthenticationMethod" ), MailTransport::Transport::EnumAuthenticationType::CLEAR); //Verify
        break;
      case 6: //APOP
        settings.insert(QLatin1String( "AuthenticationMethod" ), MailTransport::Transport::EnumAuthenticationType::APOP);
        break;
      case 10: //CRAM-MD5
        settings.insert(QLatin1String( "AuthenticationMethod" ), MailTransport::Transport::EnumAuthenticationType::CRAM_MD5);
        break;
      case 31: //Automatic
          settings.insert(QLatin1String( "AuthenticationMethod" ), MailTransport::Transport::EnumAuthenticationType::APOP); //TODO: verify
        break;
      default:
        qDebug()<<" unknown authentification method :"<<authMethod;
        break;
      }

      const QString agentIdentifyName = AbstractBase::createResource( "akonadi_pop3_resource", name, settings );
      //We have not settings for it => same than manual check
      addCheckMailOnStartup(agentIdentifyName,enableManualCheck);
      addToManualCheck(agentIdentifyName,enableManualCheck);
  } else {
      qDebug()<<" protocol unknown : "<<incomingProtocol;
  }
}

void OperaSettings::readTransport(const KConfigGroup &grp)
{
  const QString outgoingProtocol = grp.readEntry(QLatin1String("Outgoing Protocol"));
  if(outgoingProtocol == QLatin1String("SMTP")) {
      const int authMethod = grp.readEntry(QLatin1String("Outgoing Authentication Method"),-1);
      MailTransport::Transport *mt = createTransport();
      const int port = grp.readEntry(QLatin1String("Outgoing Port"), -1);
      const int secure = grp.readEntry(QLatin1String("Secure Connection Out"),-1);
      if(secure == 1) {
        mt->setEncryption( MailTransport::Transport::EnumEncryption::TLS );
      }
      if ( port > 0 )
        mt->setPort( port );

      const QString hostName = grp.readEntry(QLatin1String("Outgoing Servername"));
      mt->setHost( hostName );

      const QString userName = grp.readEntry(QLatin1String("Outgoing Username"));
      if(!userName.isEmpty())
          mt->setUserName( userName );

      const int outgoingTimeOut = grp.readEntry(QLatin1String("Outgoing Timeout"),-1); //TODO ?

      switch(authMethod) {
      case 0: //NONE
          break;
      case 2: //PLAIN
          mt->setAuthenticationType(MailTransport::Transport::EnumAuthenticationType::PLAIN);
          break;
      case 5: //LOGIN
          mt->setAuthenticationType(MailTransport::Transport::EnumAuthenticationType::LOGIN);
          break;
      case 10: //CRAM-MD5
          mt->setAuthenticationType(MailTransport::Transport::EnumAuthenticationType::CRAM_MD5);
          break;
      case 31: //Automatic
          mt->setAuthenticationType(MailTransport::Transport::EnumAuthenticationType::PLAIN); //Don't know... Verify
          break;
      default:
          qDebug()<<" authMethod unknown :"<<authMethod;
      }

      //We can't specify a default smtp...
      storeTransport( mt, true );
  }
}

void OperaSettings::readIdentity(const KConfigGroup &grp)
{
    QString realName = grp.readEntry(QLatin1String("Real Name"));
    KPIMIdentities::Identity* newIdentity = createIdentity(realName);
    const QString cc = grp.readEntry(QLatin1String("Auto CC"));
    newIdentity->setCc( cc );

    const QString bcc = grp.readEntry(QLatin1String("Auto BCC"));
    newIdentity->setBcc( bcc );

    const QString replyTo = grp.readEntry(QLatin1String("Replyto"));
    if(!replyTo.isEmpty())
      newIdentity->setReplyToAddr( replyTo );


    newIdentity->setFullName( realName );
    newIdentity->setIdentityName( realName );

    const QString email = grp.readEntry(QLatin1String("Email"));
    newIdentity->setPrimaryEmailAddress(email);

    const QString organization = grp.readEntry(QLatin1String("Organization"));
    if(!organization.isEmpty())
      newIdentity->setOrganization(organization);

    QString signatureFile = grp.readEntry(QLatin1String("Signature File"));
    if(!signatureFile.isEmpty()) {
        KPIMIdentities::Signature signature;
        const int signatureHtml = grp.readEntry(QLatin1String("Signature is HTML"),-1);
        if(signatureFile.contains(QLatin1String("{Preferences}"))) {
          signatureFile.replace(QLatin1String("{Preferences}"),MailImporter::FilterOpera::defaultSettingsPath()+QLatin1String("/"));
        }

        QFile file(signatureFile);
        if(file.exists()) {
          if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QByteArray sigText = file.readAll();

            switch(signatureHtml) {
            case -1:
                break;
            case 0:
                signature.setInlinedHtml( false );
                signature.setType( KPIMIdentities::Signature::Inlined );
                signature.setText(QString(sigText));
                break;
            case 1:
                signature.setInlinedHtml( true );
                signature.setType( KPIMIdentities::Signature::Inlined );
                signature.setText(QString(sigText));
                break;
            default:
                qDebug()<<" pb with Signature is HTML "<<signatureHtml;
                break;
            }
            newIdentity->setSignature( signature );
          }
       }
    }
    storeIdentity(newIdentity);
}

void OperaSettings::readGlobalAccount(const KConfigGroup &grp)
{
  //TODO
}
