/*
-----BEGIN QCMOD-----
name: extra
section: project
arg: disable-tests,Don't build examples and unittests.
-----END QCMOD-----
*/

class qc_extra : public ConfObj
{
public:
	qc_extra(Conf *c) : ConfObj(c) {}
	QString name() const { return "extra"; }
	QString shortname() const { return "extra"; }

	// no output
	QString checkString() const { return QString(); }

	bool exec()
	{
#ifndef Q_OS_WIN
		// --prefix=$pwd ?
		QString datadir;
		if(QFile::exists(conf->getenv("PREFIX") + "/qca.pro"))
			datadir = "$$PREFIX";
		else
			datadir = "$$DATADIR/qca";

		conf->addExtra(makeEscapedDefine("DATADIR", datadir));
#endif

		QString str;
		QFile f;

#ifndef Q_OS_WIN
		// HAVE_SYS_FILIO_H
		if(conf->findHeader("sys/filio.h", QStringList(), &str))
		{
			if(!str.isEmpty())
				conf->addIncludePath(str);
			conf->addDefine("HAVE_SYS_FILIO_H");
		}

		// MLOCK_NOT_VOID_PTR
		str =
		"# include <stdlib.h>\n"
		"# include <sys/mman.h>\n"
		"int main() { void *f = 0; return mlock(f,8); }\n";
		if(!conf->doCompileAndLink(str, QStringList(), QString(), QString()))
		{
			conf->debug("mlock(2) does not take a void *");
			conf->addDefine("MLOCK_NOT_VOID_PTR");
		}

		str = QString();
#endif

		if(conf->getenv("QC_DISABLE_TESTS") == "Y")
			str += "QCA_NO_TESTS = 1\n";

		conf->addExtra(str);

		bool release = true;
		bool debug = false;
		bool debug_info = false;
		bool universal = false;
		QString sdk;

#ifdef QC_BUILDMODE
		release = qc_buildmode_release;
		debug = qc_buildmode_debug;
		debug_info = qc_buildmode_separate_debug_info;
#endif

#ifdef QC_UNIVERSAL
		universal = qc_universal_enabled;
		sdk = qc_universal_sdk;
#endif

		// write confapp.pri
		str = QString();
#ifndef Q_OS_WIN
                QString var = conf->getenv("BINDIR");
                if(!var.isEmpty())
			str += QString("BINDIR = %1\n").arg(var);
#endif
		if(debug) // debug or debug-and-release
			str += QString("CONFIG += debug\n");
		else // release
			str += QString("CONFIG += release\n");
		if(debug_info)
		{
			str += QString("CONFIG += separate_debug_info\n");
			str += "QMAKE_CFLAGS += -g\n";
			str += "QMAKE_CXXFLAGS += -g\n";
		}
		if(universal)
		{
			str +=
			"contains(QT_CONFIG,x86):contains(QT_CONFIG,ppc) {\n"
			"	CONFIG += x86 ppc\n"
			"}\n";

			if(!sdk.isEmpty())
				str += QString("QMAKE_MAC_SDK = %1\n").arg(sdk);
		}
		f.setFileName("confapp.pri");
		if(f.open(QFile::WriteOnly | QFile::Truncate))
			f.write(str.toLatin1());
		f.close();

#ifdef Q_OS_WIN
		QString prefix = QDir::currentPath();
		QString incdir = prefix + "/include";
		QString libdir = prefix + "/lib";
#else
		QString prefix = conf->getenv("PREFIX");
		QString incdir = conf->getenv("INCDIR");
		QString libdir = conf->getenv("LIBDIR");
#endif

		// write qmake-feature file
		QString crypto_in;
		f.setFileName("crypto.prf.in");
		if(f.open(QFile::ReadOnly))
		{
			crypto_in = QString::fromUtf8(f.readAll());
			f.close();
		}

		str = QString("QCA_INCDIR = %1\n").arg(incdir);
		str += QString("QCA_LIBDIR = %1\n").arg(libdir);
		str += crypto_in;

		f.setFileName("crypto.prf");
		if(f.open(QFile::WriteOnly | QFile::Truncate))
		{
			f.write(str.toLatin1());
			f.close();
		}

#ifndef Q_OS_WIN
		str = QString(
		"prffiles.path = %1/mkspecs/features\n"
		"prffiles.files = crypto.prf\n"
		"INSTALLS += prffiles\n"
		).arg(QLibraryInfo::location(QLibraryInfo::DataPath));
		conf->addExtra(str);

		// write pkg-config files

		QString pkg_template1 = QString(
		"prefix=%1\n"
		"exec_prefix=${prefix}\n"
		"libdir=%2\n"
		"includedir=%3/QtCrypto\n"
		"\n");

		QString pkg_template2 = QString(
		"Name: %1\n"
		"Description: Qt Cryptographic Architecture library\n"
		"Version: 2.0.2\n");

		QString pkg_template3 = QString(
		"Requires: %1\n");

		QString pkg_template4 = QString(
		"Libs: -L${libdir} -l%1\n"
		"Cflags: -I${includedir}\n"
		"\n");

		QStringList pcfiles;

		QDir dir = QDir::current();
		dir.mkdir("lib");
		dir.cd("lib");
		dir.mkdir("pkgconfig");

		bool do_pc_normal = false;
		bool do_pc_debug = false;

#ifdef Q_OS_MAC
		if(release)
			do_pc_normal = true;
		if(debug)
			do_pc_debug = true;
#else
		do_pc_normal = true;
#endif

		if(do_pc_normal)
		{
			str =  pkg_template1.arg(prefix, libdir, incdir);
			str += pkg_template2.arg("QCA");
			str += pkg_template3.arg("QtCore");
			str += pkg_template4.arg("qca");
			f.setFileName("lib/pkgconfig/qca2.pc");
			if(f.open(QFile::WriteOnly | QFile::Truncate))
				f.write(str.toLatin1());
			f.close();
			pcfiles += "lib/pkgconfig/qca2.pc";
		}

		if(do_pc_debug)
		{
			str =  pkg_template1.arg(prefix, libdir, incdir);
			str += pkg_template2.arg("QCA_debug");
			str += pkg_template3.arg("QtCore_debug");
			str += pkg_template4.arg("qca_debug");
			f.setFileName("lib/pkgconfig/qca2_debug.pc");
			if(f.open(QFile::WriteOnly | QFile::Truncate))
				f.write(str.toLatin1());
			f.close();
			pcfiles += "lib/pkgconfig/qca2_debug.pc";
		}

		if(!pcfiles.isEmpty())
		{
        		str = QString(
			"pcfiles.path = $$LIBDIR/pkgconfig\n"
			"pcfiles.files = %1\n"
			"INSTALLS += pcfiles\n"
			).arg(pcfiles.join(" "));
			conf->addExtra(str);
		}
#endif

		return true;
	}

	QString makeEscapedDefine(const QString &var, const QString &val)
	{
		QString str = QString(
		"DEFINES += %1=\\\\\\\\\\\\\\"%2\\\\\\\\\\\\\\"\n"
		).arg(var).arg(val);
		return str;
	}
};
