// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package verifyApiKey

import (
	"errors"
	"github.com/apid/apidVerifyApiKey/common"
)

type DbManagerInterface interface {
	common.DbManagerInterface
	getApiKeyDetails(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) error
}

type DbManager struct {
	common.DbManager
}

func (dbc *DbManager) getApiKeyDetails(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) error {

	db := dbc.Db

	err := db.QueryRow(sql_GET_API_KEY_DETAILS_SQL, dataWrapper.verifyApiKeyRequest.Key, dataWrapper.verifyApiKeyRequest.OrganizationName).
		Scan(
			&dataWrapper.ctype,
			&dataWrapper.tenant_id,
			&dataWrapper.verifyApiKeySuccessResponse.ClientId.Status,
			&dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientSecret,

			&dataWrapper.tempDeveloperDetails.Id,
			&dataWrapper.tempDeveloperDetails.UserName,
			&dataWrapper.tempDeveloperDetails.FirstName,
			&dataWrapper.tempDeveloperDetails.LastName,
			&dataWrapper.tempDeveloperDetails.Email,
			&dataWrapper.tempDeveloperDetails.Status,
			&dataWrapper.tempDeveloperDetails.CreatedAt,
			&dataWrapper.tempDeveloperDetails.CreatedBy,
			&dataWrapper.tempDeveloperDetails.LastmodifiedAt,
			&dataWrapper.tempDeveloperDetails.LastmodifiedBy,

			&dataWrapper.verifyApiKeySuccessResponse.App.Id,
			&dataWrapper.verifyApiKeySuccessResponse.App.Name,
			&dataWrapper.verifyApiKeySuccessResponse.App.AccessType,
			&dataWrapper.verifyApiKeySuccessResponse.App.CallbackUrl,
			&dataWrapper.verifyApiKeySuccessResponse.App.DisplayName,
			&dataWrapper.verifyApiKeySuccessResponse.App.Status,
			&dataWrapper.verifyApiKeySuccessResponse.App.AppFamily,
			&dataWrapper.verifyApiKeySuccessResponse.App.Company,
			&dataWrapper.verifyApiKeySuccessResponse.App.CreatedAt,
			&dataWrapper.verifyApiKeySuccessResponse.App.CreatedBy,
			&dataWrapper.verifyApiKeySuccessResponse.App.LastmodifiedAt,
			&dataWrapper.verifyApiKeySuccessResponse.App.LastmodifiedBy,
		)

	if err != nil {
		log.Debug("error fetching verify apikey details ", err)
		return errors.New("InvalidApiKey")
	}

	if dataWrapper.verifyApiKeySuccessResponse.App.CallbackUrl != "" {
		dataWrapper.verifyApiKeySuccessResponse.ClientId.RedirectURIs = []string{dataWrapper.verifyApiKeySuccessResponse.App.CallbackUrl}
	}

	dataWrapper.apiProducts = dbc.getApiProductsForApiKey(dataWrapper.verifyApiKeyRequest.Key, dataWrapper.tenant_id)

	log.Debug("dataWrapper : ", dataWrapper)

	return err
}

func (dbc *DbManager) getApiProductsForApiKey(key, tenantId string) []ApiProductDetails {

	db := dbc.Db
	allProducts := []ApiProductDetails{}
	var proxies, environments, resources string

	rows, err := db.Query(sql_GET_API_PRODUCTS_FOR_KEY_SQL, key, tenantId)
	defer rows.Close()
	if err != nil {
		log.Error("error fetching apiProduct details", err)
		return allProducts
	}

	for rows.Next() {
		apiProductDetais := ApiProductDetails{}
		rows.Scan(
			&apiProductDetais.Id,
			&apiProductDetais.Name,
			&apiProductDetais.DisplayName,
			&apiProductDetais.QuotaLimit,
			&apiProductDetais.QuotaInterval,
			&apiProductDetais.QuotaTimeunit,
			&apiProductDetais.CreatedAt,
			&apiProductDetais.CreatedBy,
			&apiProductDetais.LastmodifiedAt,
			&apiProductDetais.LastmodifiedBy,
			&proxies,
			&environments,
			&resources,
		)
		apiProductDetais.Apiproxies = common.JsonToStringArray(proxies)
		apiProductDetais.Environments = common.JsonToStringArray(environments)
		apiProductDetais.Resources = common.JsonToStringArray(resources)

		allProducts = append(allProducts, apiProductDetais)
	}

	log.Debug("Api products retrieved for key : [%s] , tenantId : [%s] is ", key, tenantId, allProducts)

	return allProducts
}
