package apidVerifyApiKey

import (
	"database/sql"

	"github.com/30x/apid-core"
	"github.com/apigee-labs/transicator/common"
)

type handler struct {
}

func (h *handler) String() string {
	return "verifyAPIKey"
}

func (h *handler) Handle(e apid.Event) {

	snapData, ok := e.(*common.Snapshot)
	if ok {
		processSnapshot(snapData)
	} else {
		changeSet, ok := e.(*common.ChangeList)
		if ok {
			processChange(changeSet)
		} else {
			log.Errorf("Received Invalid event. Ignoring. %v", e)
		}
	}
	return
}

func processSnapshot(snapshot *common.Snapshot) {

	log.Debugf("Snapshot received. Switching to DB version: %s", snapshot.SnapshotInfo)

	db, err := data.DBVersion(snapshot.SnapshotInfo)
	if err != nil {
		log.Panicf("Unable to access database: %v", err)
	}

	createTables(db)

	if len(snapshot.Tables) > 0 {
		txn, err := db.Begin()
		if err != nil {
			log.Panicf("Unable to create transaction: %v", err)
			return
		}

		/*
		 * Iterate the tables, and insert the rows,
		 * Commit them in bulk.
		 */
		ok := true
		for _, payload := range snapshot.Tables {
			switch payload.Name {
			case "kms.developer":
				ok = insertDevelopers(payload.Rows, txn)
			case "kms.app":
				ok = insertApplications(payload.Rows, txn)
			case "kms.app_credential":
				ok = insertCredentials(payload.Rows, txn)
			case "kms.api_product":
				ok = insertAPIproducts(payload.Rows, txn)
			case "kms.app_credential_apiproduct_mapper":
				ok = insertAPIProductMappers(payload.Rows, txn)
			case "kms.company":
				ok = insertCompanies(payload.Rows, txn)
			case "kms.company_developer":
				ok = insertCompanyDevelopers(payload.Rows, txn)
			}
			if !ok {
				log.Error("Error encountered in Downloading Snapshot for VerifyApiKey")
				txn.Rollback()
				return
			}
		}
		log.Debug("Downloading Snapshot for VerifyApiKey complete")
		txn.Commit()
	}

	setDB(db)
	return
}

/*
 * Performs bulk insert of credentials
 */
func insertCredentials(rows []common.Row, txn *sql.Tx) bool {

	var scope, id, appId, consumerSecret, appstatus, status, tenantId string
	var issuedAt int64

	prep, err := txn.Prepare("INSERT INTO APP_CREDENTIAL (_change_selector, id, app_id, consumer_secret, app_status, status, issued_at, tenant_id)VALUES($1,$2,$3,$4,$5,$6,$7,$8);")
	if err != nil {
		log.Error("INSERT Cred Failed: ", err)
		return false
	}
	defer prep.Close()
	for _, ele := range rows {
		ele.Get("_change_selector", &scope)
		ele.Get("id", &id)
		ele.Get("app_id", &appId)
		ele.Get("consumer_secret", &consumerSecret)
		ele.Get("app_status", &appstatus)
		ele.Get("status", &status)
		ele.Get("issued_at", &issuedAt)
		ele.Get("tenant_id", &tenantId)

		/* Mandatory params check */
		if id == "" || scope == "" || tenantId == "" {
			log.Error("INSERT APP_CREDENTIAL: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			scope,
			id,
			appId,
			consumerSecret,
			appstatus,
			status,
			issuedAt,
			tenantId)

		if err != nil {
			log.Error("INSERT CRED Failed: ", id, ", ", scope, ")", err)
			return false
		} else {
			log.Debug("INSERT CRED Success: (", id, ", ", scope, ")")
		}
	}
	return true
}

/*
 * Performs Bulk insert of Applications
 */
func insertApplications(rows []common.Row, txn *sql.Tx) bool {

	var scope, EntityIdentifier, DeveloperId, CompanyId, ParentId, CallbackUrl, Status, AppName, AppFamily, tenantId, CreatedBy, LastModifiedBy string
	var CreatedAt, LastModifiedAt int64

	prep, err := txn.Prepare("INSERT INTO APP (_change_selector, id, developer_id, company_id, parent_id, callback_url,status, name, app_family, created_at, created_by,updated_at, updated_by,tenant_id) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);")
	if err != nil {
		log.Error("INSERT APP Failed: ", err)
		return false
	}

	defer prep.Close()
	for _, ele := range rows {

		ele.Get("_change_selector", &scope)
		ele.Get("id", &EntityIdentifier)
		ele.Get("developer_id", &DeveloperId)
		ele.Get("company_id", &CompanyId)
		ele.Get("parent_id", &ParentId)
		ele.Get("callback_url", &CallbackUrl)
		ele.Get("status", &Status)
		ele.Get("name", &AppName)
		ele.Get("app_family", &AppFamily)
		ele.Get("created_at", &CreatedAt)
		ele.Get("created_by", &CreatedBy)
		ele.Get("updated_at", &LastModifiedAt)
		ele.Get("updated_by", &LastModifiedBy)
		ele.Get("tenant_id", &tenantId)

		/* Mandatory params check */
		if EntityIdentifier == "" || scope == "" || tenantId == "" {
			log.Error("INSERT APP: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			scope,
			EntityIdentifier,
			DeveloperId,
			CompanyId,
			ParentId,
			CallbackUrl,
			Status,
			AppName,
			AppFamily,
			CreatedAt,
			CreatedBy,
			LastModifiedAt,
			LastModifiedBy,
			tenantId)

		if err != nil {
			log.Error("INSERT APP Failed: (", EntityIdentifier, ", ", tenantId, ")", err)
			return false
		} else {
			log.Debug("INSERT APP Success: (", EntityIdentifier, ", ", tenantId, ")")
		}
	}
	return true

}

/*
 * Performs bulk insert of Developers
 */
func insertDevelopers(rows []common.Row, txn *sql.Tx) bool {

	var scope, EntityIdentifier, Email, Status, UserName, FirstName, LastName, tenantId, CreatedBy, LastModifiedBy, Username string
	var CreatedAt, LastModifiedAt int64

	prep, err := txn.Prepare("INSERT INTO DEVELOPER (_change_selector,email,id,tenant_id,status,username,first_name,last_name,created_at,created_by,updated_at,updated_by) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12);")
	if err != nil {
		log.Error("INSERT DEVELOPER Failed: ", err)
		return false
	}

	defer prep.Close()
	for _, ele := range rows {

		ele.Get("_change_selector", &scope)
		ele.Get("email", &Email)
		ele.Get("id", &EntityIdentifier)
		ele.Get("tenant_id", &tenantId)
		ele.Get("status", &Status)
		ele.Get("username", &Username)
		ele.Get("first_name", &FirstName)
		ele.Get("last_name", &LastName)
		ele.Get("created_at", &CreatedAt)
		ele.Get("created_by", &CreatedBy)
		ele.Get("updated_at", &LastModifiedAt)
		ele.Get("updated_by", &LastModifiedBy)

		/* Mandatory params check */
		if EntityIdentifier == "" || scope == "" || tenantId == "" {
			log.Error("INSERT DEVELOPER: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			scope,
			Email,
			EntityIdentifier,
			tenantId,
			Status,
			UserName,
			FirstName,
			LastName,
			CreatedAt,
			CreatedBy,
			LastModifiedAt,
			LastModifiedBy)

		if err != nil {
			log.Error("INSERT DEVELOPER Failed: (", EntityIdentifier, ", ", scope, ")", err)
			return false
		} else {
			log.Debug("INSERT DEVELOPER Success: (", EntityIdentifier, ", ", scope, ")")
		}
	}
	return true
}

/*
 * Performs Bulk insert of Company Developers
 */
func insertCompanyDevelopers(rows []common.Row, txn *sql.Tx) bool {
	var scope, CompanyId, DeveloperId, tenantId, CreatedBy, LastModifiedBy string
	var CreatedAt, LastModifiedAt int64

	prep, err := txn.Prepare("INSERT INTO COMPANY_DEVELOPER (_change_selector,company_id,tenant_id,developer_id,created_at,created_by,updated_at,updated_by) VALUES($1,$2,$3,$4,$5,$6,$7,$8);")
	if err != nil {
		log.Error("INSERT COMPANY_DEVELOPER Failed: ", err)
		return false
	}
	defer prep.Close()
	for _, ele := range rows {

		ele.Get("_change_selector", &scope)
		ele.Get("company_id", &CompanyId)
		ele.Get("tenant_id", &tenantId)
		ele.Get("developer_id", &DeveloperId)
		ele.Get("created_at", &CreatedAt)
		ele.Get("created_by", &CreatedBy)
		ele.Get("updated_at", &LastModifiedAt)
		ele.Get("updated_by", &LastModifiedBy)

		/* Mandatory params check */
		if scope == "" || tenantId == "" || CompanyId == "" || DeveloperId == "" {
			log.Error("INSERT COMPANY_DEVELOPER: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			scope,
			CompanyId,
			tenantId,
			DeveloperId,
			CreatedAt,
			CreatedBy,
			LastModifiedAt,
			LastModifiedBy)

		if err != nil {
			log.Error("INSERT COMPANY_DEVELOPER Failed: (", DeveloperId, ", ", CompanyId, ", ", scope, ")", err)
			return false
		} else {
			log.Debug("INSERT COMPANY_DEVELOPER Success: (", DeveloperId, ", ", CompanyId, ", ", scope, ")")
		}
	}
	return true
}

/*
 * Performs Bulk insert of Companies
 */
func insertCompanies(rows []common.Row, txn *sql.Tx) bool {
	var scope, EntityIdentifier, Name, DisplayName, Status, tenantId, CreatedBy, LastModifiedBy string
	var CreatedAt, LastModifiedAt int64

	prep, err := txn.Prepare("INSERT INTO COMPANY (_change_selector,id,tenant_id,status,name,display_name,created_at,created_by,updated_at,updated_by) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);")
	if err != nil {
		log.Error("INSERT COMPANY Failed: ", err)
		return false
	}
	defer prep.Close()
	for _, ele := range rows {

		ele.Get("_change_selector", &scope)
		ele.Get("id", &EntityIdentifier)
		ele.Get("tenant_id", &tenantId)
		ele.Get("status", &Status)
		ele.Get("name", &Name)
		ele.Get("display_name", &DisplayName)
		ele.Get("created_at", &CreatedAt)
		ele.Get("created_by", &CreatedBy)
		ele.Get("updated_at", &LastModifiedAt)
		ele.Get("updated_by", &LastModifiedBy)

		/* Mandatory params check */
		if EntityIdentifier == "" || scope == "" || tenantId == "" {
			log.Error("INSERT COMPANY: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			scope,
			EntityIdentifier,
			tenantId,
			Status,
			Name,
			DisplayName,
			CreatedAt,
			CreatedBy,
			LastModifiedAt,
			LastModifiedBy)

		if err != nil {
			log.Error("INSERT COMPANY Failed: (", EntityIdentifier, ", ", scope, ")", err)
			return false
		} else {
			log.Debug("INSERT COMPANY Success: (", EntityIdentifier, ", ", scope, ")")
		}
	}
	return true
}

/*
 * Performs Bulk insert of API products
 */
func insertAPIproducts(rows []common.Row, txn *sql.Tx) bool {

	var scope, apiProduct, res, env, tenantId string

	prep, err := txn.Prepare("INSERT INTO API_PRODUCT (id, api_resources, environments, tenant_id,_change_selector) VALUES($1,$2,$3,$4,$5)")
	if err != nil {
		log.Error("INSERT API_PRODUCT Failed: ", err)
		return false
	}

	defer prep.Close()
	for _, ele := range rows {

		ele.Get("_change_selector", &scope)
		ele.Get("id", &apiProduct)
		ele.Get("api_resources", &res)
		ele.Get("environments", &env)
		ele.Get("tenant_id", &tenantId)

		/* Mandatory params check */
		if apiProduct == "" || scope == "" || tenantId == "" {
			log.Error("INSERT API_PRODUCT: i/p args missing")
			return false
		}
		_, err = prep.Exec(
			apiProduct,
			res,
			env,
			tenantId,
			scope)

		if err != nil {
			log.Error("INSERT API_PRODUCT Failed: (", apiProduct, ", ", tenantId, ")", err)
			return false
		} else {
			log.Debug("INSERT API_PRODUCT Success: (", apiProduct, ", ", tenantId, ")")
		}
	}
	return true
}

/*
 * Performs a bulk insert of all APP_CREDENTIAL_APIPRODUCT_MAPPER rows
 */
func insertAPIProductMappers(rows []common.Row, txn *sql.Tx) bool {

	var ApiProduct, AppId, EntityIdentifier, tenantId, Scope, Status string

	prep, err := txn.Prepare("INSERT INTO APP_CREDENTIAL_APIPRODUCT_MAPPER(apiprdt_id, app_id, appcred_id, tenant_id, _change_selector, status) VALUES($1,$2,$3,$4,$5,$6);")
	if err != nil {
		log.Error("INSERT APP_CREDENTIAL_APIPRODUCT_MAPPER Failed: ", err)
		return false
	}

	defer prep.Close()
	for _, ele := range rows {

		ele.Get("apiprdt_id", &ApiProduct)
		ele.Get("app_id", &AppId)
		ele.Get("appcred_id", &EntityIdentifier)
		ele.Get("tenant_id", &tenantId)
		ele.Get("_change_selector", &Scope)
		ele.Get("status", &Status)

		/* Mandatory params check */
		if ApiProduct == "" || AppId == "" || EntityIdentifier == "" || tenantId == "" || Scope == "" {
			log.Error("INSERT APP_CREDENTIAL_APIPRODUCT_MAPPER : i/p args missing")
			return false
		}

		/*
		 * If the credentials has been successfully inserted, insert the
		 * mapping entries associated with the credential
		 */

		_, err = prep.Exec(
			ApiProduct,
			AppId,
			EntityIdentifier,
			tenantId,
			Scope,
			Status)

		if err != nil {
			log.Error("INSERT APP_CREDENTIAL_APIPRODUCT_MAPPER Failed: (",
				ApiProduct, ", ",
				AppId, ", ",
				EntityIdentifier, ", ",
				tenantId, ", ",
				Scope, ", ",
				Status,
				")",
				err)

			return false
		} else {
			log.Debug("INSERT APP_CREDENTIAL_APIPRODUCT_MAPPER Success: (",
				ApiProduct, ", ",
				AppId, ", ",
				EntityIdentifier, ", ",
				tenantId, ", ",
				Scope, ", ",
				Status,
				")")
		}
	}
	return true
}

func processChange(changes *common.ChangeList) {

	db := getDB()

	txn, err := db.Begin()
	if err != nil {
		log.Error("Unable to create transaction")
		return
	}
	defer txn.Rollback()

	var rows []common.Row
	ok := true

	log.Debugf("apigeeSyncEvent: %d changes", len(changes.Changes))
	for _, payload := range changes.Changes {
		rows = nil
		switch payload.Table {
		case "kms.developer":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertDevelopers(rows, txn)

			case common.Update:
				ok = deleteObject("DEVELOPER", payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertDevelopers(rows, txn)

			case common.Delete:
				ok = deleteObject("DEVELOPER", payload.OldRow, txn)
			}
		case "kms.app":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertApplications(rows, txn)

			case common.Update:
				ok = deleteObject("APP", payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertApplications(rows, txn)

			case common.Delete:
				ok = deleteObject("APP", payload.OldRow, txn)
			}
		case "kms.company":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertCompanies(rows, txn)

			case common.Update:
				ok = deleteObject("COMPANY", payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertCompanies(rows, txn)

			case common.Delete:
				ok = deleteObject("COMPANY", payload.OldRow, txn)
			}
		case "kms.company_developer":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertCompanyDevelopers(rows, txn)

			case common.Update:
				ok = deleteCompanyDeveloper(payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertCompanyDevelopers(rows, txn)

			case common.Delete:
				ok = deleteCompanyDeveloper(payload.OldRow, txn)
			}
		case "kms.app_credential":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertCredentials(rows, txn)

			case common.Update:
				ok = deleteObject("APP_CREDENTIAL", payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertCredentials(rows, txn)

			case common.Delete:
				ok = deleteObject("APP_CREDENTIAL", payload.OldRow, txn)
			}
		case "kms.api_product":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertAPIproducts(rows, txn)

			case common.Update:
				ok = deleteObject("API_PRODUCT", payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertAPIproducts(rows, txn)

			case common.Delete:
				ok = deleteObject("API_PRODUCT", payload.OldRow, txn)
			}

		case "kms.app_credential_apiproduct_mapper":
			switch payload.Operation {
			case common.Insert:
				rows = append(rows, payload.NewRow)
				ok = insertAPIProductMappers(rows, txn)

			case common.Update:
				ok = deleteAPIproductMapper(payload.OldRow, txn)
				rows = append(rows, payload.NewRow)
				ok = insertAPIProductMappers(rows, txn)

			case common.Delete:
				ok = deleteAPIproductMapper(payload.OldRow, txn)
			}
		}
		if !ok {
			log.Error("Sql Operation error. Operation rollbacked")
			return
		}
	}
	txn.Commit()
	return
}

/*
 * DELETE OBJECT as passed in the input
 */
func deleteObject(object string, ele common.Row, txn *sql.Tx) bool {

	var scope, objid string
	ssql := "DELETE FROM " + object + " WHERE id = $1 AND _change_selector = $2"
	prep, err := txn.Prepare(ssql)
	if err != nil {
		log.Error("DELETE ", object, " Failed: ", err)
		return false
	}
	defer prep.Close()
	ele.Get("_change_selector", &scope)
	ele.Get("id", &objid)

	res, err := prep.Exec(objid, scope)
	if err == nil {
		affect, err := res.RowsAffected()
		if err == nil && affect != 0 {
			log.Debugf("DELETE %s (%s, %s) success.", object, objid, scope)
			return true
		}
	}
	log.Errorf("DELETE %s (%s, %s) failed.", object, objid, scope)
	return false

}

/*
 * DELETE  APIPRDT MAPPER
 */
func deleteAPIproductMapper(ele common.Row, txn *sql.Tx) bool {
	var ApiProduct, AppId, EntityIdentifier, apid_scope string

	prep, err := txn.Prepare("DELETE FROM APP_CREDENTIAL_APIPRODUCT_MAPPER WHERE apiprdt_id=$1 AND app_id=$2 AND appcred_id=$3 AND _change_selector=$4;")
	if err != nil {
		log.Error("DELETE APP_CREDENTIAL_APIPRODUCT_MAPPER Failed: ", err)
		return false
	}

	defer prep.Close()

	ele.Get("apiprdt_id", &ApiProduct)
	ele.Get("app_id", &AppId)
	ele.Get("appcred_id", &EntityIdentifier)
	ele.Get("_change_selector", &apid_scope)

	res, err := prep.Exec(ApiProduct, AppId, EntityIdentifier, apid_scope)
	if err == nil {
		affect, err := res.RowsAffected()
		if err == nil && affect != 0 {
			log.Debugf("DELETE APP_CREDENTIAL_APIPRODUCT_MAPPER (%s, %s, %s, %s) success.", ApiProduct, AppId, EntityIdentifier, apid_scope)
			return true
		}
	}
	log.Errorf("DELETE APP_CREDENTIAL_APIPRODUCT_MAPPER (%s, %s, %s, %s) failed.", ApiProduct, AppId, EntityIdentifier, apid_scope, err)
	return false
}

func deleteCompanyDeveloper(ele common.Row, txn *sql.Tx) bool {
	prep, err := txn.Prepare(`
	DELETE FROM COMPANY_DEVELOPER
	WHERE tenant_id=$1 AND company_id=$2 AND developer_id=$3`)
	if err != nil {
		log.Errorf("DELETE COMPANY_DEVELOPER Failed: %v", err)
		return false
	}
	defer prep.Close()

	var tenantId, companyId, developerId string
	ele.Get("tenant_id", &tenantId)
	ele.Get("company_id", &companyId)
	ele.Get("developer_id", &developerId)

	res, err := prep.Exec(tenantId, companyId, developerId)
	if err == nil {
		affect, err := res.RowsAffected()
		if err == nil && affect != 0 {
			log.Debugf("DELETE COMPANY_DEVELOPER (%s, %s, %s) success.", tenantId, companyId, developerId)
			return true
		}
	}
	log.Errorf("DELETE COMPANY_DEVELOPER (%s, %s, %s) failed: %v", tenantId, companyId, developerId, err)
	return false
}
