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)
			}
			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, Name string
	var CreatedAt, LastModifiedAt int64

	prep, err := txn.Prepare("INSERT INTO DEVELOPER (_change_selector,email,id,tenant_id,status,username,first_name,last_name,name,created_at,created_by,updated_at,updated_by) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13);")
	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("email", &Name)
		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,
			Name,
			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
}
