/***************************************************************************
 *   Copyright (C) 2001 by Matthias Hoelzer-Kluepfel <mhk@caldera.de>      *
 *                                                                         *
 *   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 "usbdb.h"

#include <iostream>

#include <QFile>
#include <QRegExp>
#include <QTextStream>
#include <QStandardPaths>
#include <QDebug>

USBDB::USBDB() {
	QString db = QStringLiteral("/usr/share/hwdata/usb.ids"); /* on Fedora and Arch*/
	if (!QFile::exists(db)) {
                //cannot use locate(AppDataLocation) as the app is kinfocenter
		db = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kcmusb"), QStandardPaths::LocateDirectory);
                if (!db.isEmpty())
                    db+=QLatin1String("/usb.ids");
        }
	if (db.isEmpty())
		return;

	QFile f(db);

	if (f.open(QIODevice::ReadOnly)) {
		QTextStream ts(&f);
		ts.setCodec("UTF-8");

		QString line, name;
		int id=0, subid=0, protid=0;
		QRegExp vendor(QStringLiteral("[0-9a-fA-F]+ "));
		QRegExp product(QStringLiteral("\\s+[0-9a-fA-F]+ "));
		QRegExp cls(QStringLiteral("C [0-9a-fA-F][0-9a-fA-F]"));
		QRegExp subclass(QStringLiteral("\\s+[0-9a-fA-F][0-9a-fA-F]  "));
		QRegExp prot(QStringLiteral("\\s+[0-9a-fA-F][0-9a-fA-F]  "));
		while (!ts.atEnd()) {
			line = ts.readLine();
            if (!line.isEmpty() && (line.at(0) == QLatin1String("#") || line.trimmed().isEmpty()))
				continue;

			// skip AT lines
			if (line.left(2) == QLatin1String("AT"))
				continue;

			if (cls.indexIn(line) == 0 && cls.matchedLength() == 4) {
				id = line.midRef(2,2).toInt(0, 16);
				name = line.mid(4).trimmed();
				_classes.insert(QStringLiteral("%1").arg(id), name);
			} else if (prot.indexIn(line) == 0 && prot.matchedLength() > 5) {
				line = line.trimmed();
				protid = line.leftRef(2).toInt(0, 16);
				name = line.mid(4).trimmed();
				_classes.insert(QStringLiteral("%1-%2-%3").arg(id).arg(subid).arg(protid), name);
			} else if (subclass.indexIn(line) == 0 && subclass.matchedLength() > 4) {
				line = line.trimmed();
				subid = line.leftRef(2).toInt(0, 16);
				name = line.mid(4).trimmed();
				_classes.insert(QStringLiteral("%1-%2").arg(id).arg(subid), name);
			} else if (vendor.indexIn(line) == 0 && vendor.matchedLength() == 5) {
				id = line.leftRef(4).toInt(0, 16);
				name = line.mid(6);
				_ids.insert(QStringLiteral("%1").arg(id), name);
			} else if (product.indexIn(line) == 0 && product.matchedLength() > 5) {
				line = line.trimmed();
				subid = line.leftRef(4).toInt(0, 16);
				name = line.mid(6);
				_ids.insert(QStringLiteral("%1-%2").arg(id).arg(subid), name);
			}

		}

		f.close();
	}
}

QString USBDB::vendor(int id) {
	QString s = _ids[QStringLiteral("%1").arg(id)];
	if (id != 0) {
		return s;
	}
	return QString();
}

QString USBDB::device(int vendor, int id) {
	QString s = _ids[QStringLiteral("%1-%2").arg(vendor).arg(id)];
	if ((id != 0) && (vendor != 0))
		return s;
	return QString();
}

QString USBDB::cls(int cls) {
	return _classes[QStringLiteral("%1").arg(cls)];
}

QString USBDB::subclass(int cls, int sub) {
	return _classes[QStringLiteral("%1-%2").arg(cls).arg(sub)];
}

QString USBDB::protocol(int cls, int sub, int prot) {
	return _classes[QStringLiteral("%1-%2-%3").arg(cls).arg(sub).arg(prot)];
}

