/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QMap>
#include <QPair>
#include <QString>
#include <QVector>

#include "src/datovka_shared/io/db_tables.h"
#include "src/io/account_db_tables.h"

namespace AccntinfTbl {
	const QString tabName("account_info");

	const QVector< QPair<QString, enum EntryType> > knownAttrs = {
	{"key", DB_TEXT}, /* NOT NULL */
	{"dbID", DB_TEXT}, /* NOT NULL */
	{"dbType", DB_TEXT},
	{"ic", DB_INTEGER},
	{"pnFirstName", DB_TEXT},
	{"pnMiddleName", DB_TEXT},
	{"pnLastName", DB_TEXT},
	{"pnLastNameAtBirth", DB_TEXT},
	{"firmName", DB_TEXT},
	{"biDate", DB_DATE},
	{"biCity", DB_TEXT},
	{"biCounty", DB_TEXT},
	{"biState", DB_TEXT},
	{"adCity", DB_TEXT},
	{"adStreet", DB_TEXT},
	{"adNumberInStreet", DB_TEXT},
	{"adNumberInMunicipality", DB_TEXT},
	{"adZipCode", DB_TEXT},
	{"adState", DB_TEXT},
	{"nationality", DB_TEXT},
	{"identifier", DB_TEXT},
	{"registryCode", DB_TEXT},
	{"dbState", DB_INTEGER},
	{"dbEffectiveOVM", DB_BOOLEAN},
	{"dbOpenAddressing", DB_BOOLEAN}
	};

	const QMap<QString, QString> colConstraints = {
	    {"key", "NOT NULL"},
	    {"dbID", "NOT NULL"}
	};

	const QString tblConstraint = {
	    ",\n"
	    "        PRIMARY KEY (key),\n"
	    "        CHECK (dbEffectiveOVM IN (0, 1)),\n"
	    "        CHECK (dbOpenAddressing IN (0, 1))"
	};

	QMap<QString, SQLiteTbl::AttrProp> attrProps = {
	{"key",                    {DB_TEXT, ""}},
	{"dbID",                   {DB_TEXT, SQLiteTbls::tr("Data box ID")}},
	{"dbType",                 {DB_TEXT, SQLiteTbls::tr("Data box type")}},
	{"ic",                     {DB_INTEGER, SQLiteTbls::tr("Identification number (IČO)")}},
	{"pnFirstName",            {DB_TEXT, SQLiteTbls::tr("Given name")}},
	{"pnMiddleName",           {DB_TEXT, SQLiteTbls::tr("Middle name")}},
	{"pnLastName",             {DB_TEXT, SQLiteTbls::tr("Surname")}},
	{"pnLastNameAtBirth",      {DB_TEXT, SQLiteTbls::tr("Surname at birth")}},
	{"firmName",               {DB_TEXT, SQLiteTbls::tr("Company name")}},
	{"biDate",                 {DB_DATE, SQLiteTbls::tr("Date of birth")}},
	{"biCity",                 {DB_TEXT, SQLiteTbls::tr("City of birth")}},
	{"biCounty",               {DB_TEXT, SQLiteTbls::tr("County of birth")}},
	{"biState",                {DB_TEXT, SQLiteTbls::tr("State of birth")}},
	{"adCity",                 {DB_TEXT, SQLiteTbls::tr("City of residence")}},
	{"adStreet",               {DB_TEXT, SQLiteTbls::tr("Street of residence")}},
	{"adNumberInStreet",       {DB_TEXT, SQLiteTbls::tr("Number in street")}},
	{"adNumberInMunicipality", {DB_TEXT, SQLiteTbls::tr("Number in municipality")}},
	{"adZipCode",              {DB_TEXT, SQLiteTbls::tr("Zip code")}},
	{"adState",                {DB_TEXT, SQLiteTbls::tr("State of residence")}},
	{"nationality",            {DB_TEXT, SQLiteTbls::tr("Nationality")}},
	{"identifier",             {DB_TEXT, ""}}, //
	{"registryCode",           {DB_TEXT, ""}}, //
	{"dbState",                {DB_INTEGER, SQLiteTbls::tr("Databox state")}},
	{"dbEffectiveOVM",         {DB_BOOLEAN, SQLiteTbls::tr("Effective OVM")}},
	{"dbOpenAddressing",       {DB_BOOLEAN, SQLiteTbls::tr("Open addressing")}}
	};
} /* namespace AccntinfTbl */
SQLiteTbl accntinfTbl(AccntinfTbl::tabName, AccntinfTbl::knownAttrs,
    AccntinfTbl::attrProps, AccntinfTbl::colConstraints,
    AccntinfTbl::tblConstraint);

namespace UserinfTbl {
	const QString tabName("user_info");

	const QVector< QPair<QString, enum EntryType> > knownAttrs = {
	{"key", DB_TEXT}, /* NOT NULL */
	{"userType", DB_TEXT},
	{"userPrivils", DB_INTEGER},
	{"pnFirstName", DB_TEXT},
	{"pnMiddleName", DB_TEXT},
	{"pnLastName", DB_TEXT},
	{"pnLastNameAtBirth", DB_TEXT},
	{"adCity", DB_TEXT},
	{"adStreet", DB_TEXT},
	{"adNumberInStreet", DB_TEXT},
	{"adNumberInMunicipality", DB_TEXT},
	{"adZipCode", DB_TEXT},
	{"adState", DB_TEXT},
	{"biDate", DB_DATE},
	{"ic", DB_INTEGER},
	{"firmName", DB_TEXT},
	{"caStreet", DB_TEXT},
	{"caCity", DB_TEXT},
	{"caZipCode", DB_TEXT},
	{"caState", DB_TEXT},
	};

	const QMap<QString, QString> colConstraints = {
	    {"key", "NOT NULL"}
	};

	const QString tblConstraint = {
	    ",\n"
	    "        PRIMARY KEY (key)"
	};

	QMap<QString, SQLiteTbl::AttrProp> attrProps = {
	{"key",                    {DB_TEXT, ""}},
	{"userType",               {DB_TEXT, SQLiteTbls::tr("User type")}},
	{"userPrivils",            {DB_INTEGER, SQLiteTbls::tr("Permissions")}},
	{"pnFirstName",            {DB_TEXT, SQLiteTbls::tr("Given name")}},
	{"pnMiddleName",           {DB_TEXT, SQLiteTbls::tr("Middle name")}},
	{"pnLastName",             {DB_TEXT, SQLiteTbls::tr("Surname")}},
	{"pnLastNameAtBirth",      {DB_TEXT, SQLiteTbls::tr("Surname at birth")}},
	{"adCity",                 {DB_TEXT, SQLiteTbls::tr("City")}},
	{"adStreet",               {DB_TEXT, SQLiteTbls::tr("Street")}},
	{"adNumberInStreet",       {DB_TEXT, SQLiteTbls::tr("Number in street")}},
	{"adNumberInMunicipality", {DB_TEXT, SQLiteTbls::tr("Number in municipality")}},
	{"adZipCode",              {DB_TEXT, SQLiteTbls::tr("Zip code")}},
	{"adState",                {DB_TEXT, SQLiteTbls::tr("State")}},
	{"biDate",                 {DB_DATE, SQLiteTbls::tr("Date of birth")}},
	{"ic",                     {DB_INTEGER, SQLiteTbls::tr("Identification number (IČO)")}},
	{"firmName",               {DB_TEXT, SQLiteTbls::tr("Company name")}},
	{"caStreet",               {DB_TEXT, SQLiteTbls::tr("Street of residence")}},
	{"caCity",                 {DB_TEXT, SQLiteTbls::tr("City of residence")}},
	{"caZipCode",              {DB_TEXT, SQLiteTbls::tr("Zip code")}},
	{"caState",                {DB_TEXT, SQLiteTbls::tr("State of residence")}}
	};
} /* namespace UserinfTbl */
SQLiteTbl userinfTbl(UserinfTbl::tabName, UserinfTbl::knownAttrs,
    UserinfTbl::attrProps, UserinfTbl::colConstraints,
    UserinfTbl::tblConstraint);

namespace PwdexpdtTbl {
	const QString tabName("password_expiration_date");

	const QVector< QPair<QString, enum EntryType> > knownAttrs = {
	{"key", DB_TEXT}, /* NOT NULL */
	{"expDate", DB_TEXT}
	};

	const QMap<QString, QString> colConstraints = {
	    {"key", "NOT NULL"}
	};

	const QString tblConstraint = {
	    ",\n"
	    "        PRIMARY KEY (key)"
	};

	const QMap<QString, SQLiteTbl::AttrProp> attrProps = {
	{"key",     {DB_TEXT, ""}},
	{"expDate", {DB_TEXT, ""}}
	};
} /* namespace PwdexpdtTbl */
SQLiteTbl pwdexpdtTbl(PwdexpdtTbl::tabName, PwdexpdtTbl::knownAttrs,
    PwdexpdtTbl::attrProps, PwdexpdtTbl::colConstraints,
    PwdexpdtTbl::tblConstraint);

namespace DTinfTbl {
	const QString tabName("dt_info");

	const QVector< QPair<QString, enum EntryType> > knownAttrs = {
	{"test_env", DB_BOOLEAN}, /* NOT NULL */
	{"dbID", DB_TEXT}, /* NOT NULL */
	{"actDTType", DB_INTEGER},
	{"actDTCapacity", DB_INTEGER},
	{"actDTFrom", DB_DATE},
	{"actDTTo", DB_DATE},
	{"actDTCapUsed", DB_INTEGER},
	{"futDTType", DB_INTEGER},
	{"futDTCapacity", DB_INTEGER},
	{"futDTFrom", DB_DATE},
	{"futDTTo", DB_DATE},
	{"futDTPaid", DB_INTEGER}
	};

	const QMap<QString, QString> colConstraints = {
	    {"test_env", "NOT NULL"},
	    {"dbID", "NOT NULL"}
	};

	const QString tblConstraint = {
	    ",\n"
	    "        CHECK (test_env IN (0, 1)),\n"
	    "        UNIQUE (test_env, dbID)"
	};

	QMap<QString, SQLiteTbl::AttrProp> attrProps = {
	{"test_env",      {DB_BOOLEAN, SQLiteTbls::tr("Public test environment data box")}},
	{"dbID",          {DB_TEXT, SQLiteTbls::tr("Data-box ID")}},
	{"actDTType",     {DB_INTEGER, SQLiteTbls::tr("Current long-term storage type")}},
	{"actDTCapacity", {DB_INTEGER, SQLiteTbls::tr("Current long-term storage capacity")}},
	{"actDTFrom",     {DB_DATE, SQLiteTbls::tr("Current long-term storage active from")}},
	{"actDTTo",       {DB_DATE, SQLiteTbls::tr("Current long-term storage active to")}},
	{"actDTCapUsed",  {DB_INTEGER, SQLiteTbls::tr("Current long-term storage capacity used")}},
	{"futDTType",     {DB_INTEGER, SQLiteTbls::tr("Future long-term storage type")}},
	{"futDTCapacity", {DB_INTEGER, SQLiteTbls::tr("Future long-term storage capacity")}},
	{"futDTFrom",     {DB_DATE, SQLiteTbls::tr("Future long-term storage active from")}},
	{"futDTTo",       {DB_DATE, SQLiteTbls::tr("Future long-term storage active to")}},
	{"futDTPaid",     {DB_INTEGER, SQLiteTbls::tr("Future long-term storage payment state")}}
	};
} /* namespace DTinfTbl */
SQLiteTbl dtinfTbl(DTinfTbl::tabName, DTinfTbl::knownAttrs, DTinfTbl::attrProps,
    DTinfTbl::colConstraints, DTinfTbl::tblConstraint);
