//=============================================================================
//  MuseScore
//  Music Composition & Notation
//
//  Copyright (C) 2012-2013 Werner Schweer
//
//  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 and appearing in
//  the file LICENCE.GPL
//=============================================================================

#include "testbase.h"

#include <QtTest/QtTest>
#include <QTextStream>

#include "config.h"
#include "libmscore/score.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/musescoreCore.h"

namespace Ms {
extern bool saveBraille(Score* score, const QString& name);
}

namespace Ms {
MTest::MTest()
{
    MScore::testMode = true;
}

MasterScore* MTest::readScore(const QString& name)
{
    QString path = root + "/" + name;
    MasterScore* score = new MasterScore(mscore->baseStyle());
    QFileInfo fi(path);
    score->setName(fi.completeBaseName());
    QString csl  = fi.suffix().toLower();

    ScoreLoad sl;
    Score::FileError rv;
    if (csl == "mscz" || csl == "mscx") {
        rv = score->loadMsc(path, false);
    } else {
        rv = Score::FileError::FILE_UNKNOWN_TYPE;
    }

    if (rv != Score::FileError::FILE_NO_ERROR) {
        QWARN(qPrintable(QString("readScore: cannot load <%1> type <%2>\n").arg(path).arg(csl)));
        delete score;
        score = 0;
    } else {
        for (Score* s : score->scoreList()) {
            s->doLayout();
        }
    }
    return score;
}

bool MTest::saveScore(Score* score, const QString& name) const
{
    QFileInfo fi(name);
//      MScore::testMode = true;
    return score->Score::saveFile(fi);
}

bool MTest::compareFilesFromPaths(const QString& f1, const QString& f2)
{
    QString cmd = "diff";
    QStringList args;
    args.append("-u");
    args.append("--strip-trailing-cr");
    args.append(f2);
    args.append(f1);
    QProcess p;
    qDebug() << "Running " << cmd << " with arg1: " << QFileInfo(f2).fileName() << " and arg2: "
             << QFileInfo(f1).fileName();
    p.start(cmd, args);
    if (!p.waitForFinished() || p.exitCode()) {
        QByteArray ba = p.readAll();
        //qDebug("%s", qPrintable(ba));
        //qDebug("   <diff -u %s %s failed", qPrintable(compareWith),
        //   qPrintable(QString(root + "/" + saveName)));
        QTextStream outputText(stdout);
        outputText << QString(ba);
        outputText << QString("   <diff -u %1 %2 failed").arg(f2).arg(f1);
        return false;
    }
    return true;
}

bool MTest::compareFiles(const QString& saveName, const QString& compareWith) const
{
    return compareFilesFromPaths(saveName, root + "/" + compareWith);
}

bool MTest::saveCompareScore(Score* score, const QString& saveName, const QString& compareWith) const
{
    if (!saveScore(score, saveName)) {
        return false;
    }
    return compareFiles(saveName, compareWith);
}

bool MTest::saveBraille(MasterScore* score, const QString& saveName)
{
    return Ms::saveBraille(score, saveName);
}

bool MTest::saveCompareBrailleScore(MasterScore* score, const QString& saveName, const QString& compareWith)
{
    saveBraille(score, saveName);
    return compareFiles(saveName, compareWith);
}

void MTest::initMTest(const QString& rootDir)
{
    MScore::noGui = true;

    mscore = new MScore;
    new MuseScoreCore;
    mscore->init();

    root = rootDir;
    loadInstrumentTemplates(":/instruments.xml");
}
}
