/*
Copyright (c) 2010 by Drake Justice <djustice.kde@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 2 of the License, or
(at your option) any later version.
*/

#include <QMessageBox>
#include <QDebug>

#include <KLocale>

#include "copythread.h"

CopyThread::CopyThread(QObject* parent, const QString &device, Solid::OpticalDisc::ContentTypes disctype): QThread(parent)
{
    m_device = device;
    m_discType = disctype;
    m_hadError = false;
    m_wasCanceled = false;
}

void CopyThread::run()
{
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(updateProgress()));
    connect(&m_process, SIGNAL(finished(int)), this, SLOT(processFinished(int)));
    connect(&m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));

    m_process.setProcessChannelMode(QProcess::MergedChannels);
    
    if (m_discType == Solid::OpticalDisc::Audio)
    {
        m_process.start("cdrdao copy -v 5 --device " + m_device);
    } else {
        m_process.start("dd if=" + m_device + " of=" + m_filename);
    }

    m_pid = (int) m_process.pid();
    m_timer.start(3000);
    exec();
}

void CopyThread::processFinished(int exit_code)
{
    m_timer.stop();

    emit finished();

    if(m_wasCanceled)
        return;
    
    if(exit_code == QProcess::NormalExit)
    {
        QMessageBox::information(0, "DiscBurner", i18n("Copy completed"));
    }
}

void CopyThread::processError(QProcess::ProcessError error)
{
    QMessageBox::information(0, "test", "CopyThread::processError()");
    m_hadError = true;

    if(m_wasCanceled)
        return;

    switch(error)
    {
    case 0:
        QMessageBox::information(0, "DiscBurner", i18n("Could not start copying. Check whether you have sufficient permissions."));
        break;

    case 1:
        QMessageBox::information(0, "DiscBurner", i18n("Copying process crashed."));
        break;

    case 2:
        QMessageBox::information(0, "DiscBurner", i18n("Copying failed: timed out."));
        break;

    case 3:
        QMessageBox::information(0, "DiscBurner", i18n("Copying failed: cannot communicate with copy process."));
        break;

    case 4:
        QMessageBox::information(0, "DiscBurner", i18n("Copying failed due to a write error. Check disk space and permissions."));
        break;

    case 5:
        QMessageBox::information(0, "DiscBurner", i18n("Copying failed with an unknown error."));
        break;
    };
}

void CopyThread::updateProgress()
{
  qDebug() << "CopyThread::updateProgress()";
    QString output;
    QProcess p_update;
    
    if (m_discType == Solid::OpticalDisc::Audio)
    {
        output = m_process.readAll();
  qDebug() << output;
        foreach (const QString &line, output.split('\n')) {
            if (line.contains("Copying audio tracks")) {
                emit discCapacity(line.split(" ", QString::SkipEmptyParts).at(7).split(":", QString::SkipEmptyParts).at(0).toInt());
            }

            if (line.contains(QRegExp(":*:")) && line.at(2) == QChar(':')) {
                emit progressMonitor(line.split(":", QString::SkipEmptyParts).at(0).toInt());
            }

            if (line.contains("Please insert a")) {
                emit ejectTray();
            }
        }
    } else {
        p_update.start("kill -s USR1 " + QString::number(m_pid));
        p_update.waitForFinished();
        output = m_process.readAll();
  qDebug() << output;
        foreach (const QString& line, output.split('\n')) {
            if(line.contains("bytes")) {
                emit progressMonitor(line.split(" ", QString::SkipEmptyParts).at(0).toInt() / 1024 / 1024);
            }
        }
    }
}

void CopyThread::cancelProcess()
{
    m_process.kill();
    m_wasCanceled = true;
}

void CopyThread::blankDiscInserted()
{
  qDebug() << "CopyThread::blankDiscInserted()";
    m_process.write("\n\r");
    m_process.closeWriteChannel();
}

#include "copythread.h"
