// 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 apidVerifyApiKey

import (
	"database/sql"
	"encoding/json"
	"errors"
	"github.com/30x/apid-core"
	"io"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"unicode/utf8"
)

type apiManagerInterface interface {
	InitAPI()
	//addChangedDeployment(string)
	//distributeEvents()
}
type apiManager struct {
	dbMan             dbManagerInterface
	verifiersEndpoint string
	apiInitialized    bool
}

func (a *apiManager) InitAPI() {
	if a.apiInitialized {
		return
	}
	services.API().HandleFunc(a.verifiersEndpoint, a.handleRequest).Methods("POST")
	a.apiInitialized = true
	log.Debug("API endpoints initialized")
}

// handle client API
func (a *apiManager) handleRequest(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	verifyApiKeyReq, err := validateRequest(r.Body, w)
	if err != nil {
		return
	}

	b, err := verifyAPIKey(verifyApiKeyReq, a.dbMan.getDb())

	if err != nil {
		respStatusCode, atoierr := strconv.Atoi(err.Error())
		if atoierr != nil {
			w.WriteHeader(http.StatusInternalServerError)
		} else {
			w.WriteHeader(respStatusCode)
		}
	}

	log.Debugf("handleVerifyAPIKey result %s", b)
	w.Write(b)
	return
}

func validateRequest(requestBody io.ReadCloser, w http.ResponseWriter) (VerifyApiKeyRequest, error) {
	// 1. read request boby
	var verifyApiKeyReq VerifyApiKeyRequest
	body, err := ioutil.ReadAll(requestBody)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte(err.Error()))
		return verifyApiKeyReq, errors.New("Bad_REQUEST")
	}
	log.Debug(string(body))
	// 2. umarshall json to struct
	err = json.Unmarshal(body, &verifyApiKeyReq)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		w.Write([]byte(err.Error()))
		return verifyApiKeyReq, errors.New("Bad_REQUEST")
	}
	log.Debug(verifyApiKeyReq)

	// 2. verify params
	if verifyApiKeyReq.Action == "" || verifyApiKeyReq.ApiProxyName == "" || verifyApiKeyReq.EnvironmentName == "" || verifyApiKeyReq.Key == "" {
		// TODO : set correct fields in error response
		errorResponse := errorResponse("Bad_REQUEST", "Missing element")
		w.WriteHeader(http.StatusBadRequest)
		w.Write(errorResponse)
		return verifyApiKeyReq, errors.New("Bad_REQUEST")
	}
	return verifyApiKeyReq, nil
}

// returns []byte to be written to client
func verifyAPIKey(verifyApiKeyReq VerifyApiKeyRequest, db apid.DB) ([]byte, error) {

	/* these fields need to be nullable types for scanning.  This is because when using json snapshots,
	   and therefore being responsible for inserts, we were able to default everything to be not null.  With
	   sqlite snapshots, we are not necessarily guaranteed that
	*/
	var finalDeveloperDetails DeveloperDetails
	var companyDetails CompanyDetails
	var cType, tenantId sql.NullString

	tempDeveloperDetails := DeveloperDetails{}
	appDetails := AppDetails{}
	apiProductDetails := ApiProductDetails{}
	clientIdDetails := ClientIdDetails{}
	clientIdDetails.ClientId = verifyApiKeyReq.Key

	err := getApiKeyDetails(db, verifyApiKeyReq, &cType, &tenantId, &tempDeveloperDetails, &appDetails, &apiProductDetails, &clientIdDetails)

	switch {
	case err == sql.ErrNoRows:
		reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode := "oauth.v2.InvalidApiKey"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))

	case err != nil:
		reason := err.Error()
		errorCode := "SEARCH_INTERNAL_ERROR"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusInternalServerError))
	}

	/*
	 * Perform all validations related to the Query made with the data
	 * we just retrieved
	 */
	errResponse, err := performValidations(verifyApiKeyReq, clientIdDetails, appDetails, tempDeveloperDetails, apiProductDetails, cType)

	if errResponse != nil {
		return errResponse, err
	}

	enrichAttributes(db, tenantId.String, &clientIdDetails, &appDetails, &tempDeveloperDetails, &apiProductDetails)

	if cType.String == "developer" {
		finalDeveloperDetails = tempDeveloperDetails
	} else {
		companyDetails = CompanyDetails{
			Id:             tempDeveloperDetails.Id,
			DisplayName:    tempDeveloperDetails.UserName,
			Status:         tempDeveloperDetails.Status,
			CreatedAt:      tempDeveloperDetails.CreatedAt,
			CreatedBy:      tempDeveloperDetails.CreatedBy,
			LastmodifiedAt: tempDeveloperDetails.LastmodifiedAt,
			LastmodifiedBy: tempDeveloperDetails.LastmodifiedBy,
			Attributes:     tempDeveloperDetails.Attributes,
		}

	}

	resp := VerifyApiKeySuccessResponse{
		ClientId:     clientIdDetails,
		Organization: verifyApiKeyReq.OrganizationName,
		Environment:  verifyApiKeyReq.EnvironmentName,
		Developer:    finalDeveloperDetails,
		Company:      companyDetails,
		App:          appDetails,
		ApiProduct:   apiProductDetails,
		// Identifier of the authorization code. This will be unique for each request.
		Identifier: verifyApiKeyReq.Key, // TODO : what is this ?????
		Kind:       "Collection",        // TODO : what is this ????

	}

	return json.Marshal(resp)
}

func performValidations(verifyApiKeyReq VerifyApiKeyRequest, clientIdDetails ClientIdDetails, appDetails AppDetails, tempDeveloperDetails DeveloperDetails, apiProductDetails ApiProductDetails, cType sql.NullString) ([]byte, error) {
	if !strings.EqualFold("APPROVED", clientIdDetails.Status) {
		reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode := "oauth.v2.ApiKeyNotApproved"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	if !strings.EqualFold("APPROVED", appDetails.Status) {
		reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode := "keymanagement.service.invalid_client-app_not_approved"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	if !strings.EqualFold("ACTIVE", tempDeveloperDetails.Status) {
		reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode := "keymanagement.service.DeveloperStatusNotActive"
		if cType.String == "company" {
			errorCode = "keymanagement.service.CompanyStatusNotActive"
		}
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	result := validatePathRegex(apiProductDetails.Resources, verifyApiKeyReq.UriPath)
	if result == false {
		reason := "Path Validation Failed (" + strings.Join(apiProductDetails.Resources, ", ") + " vs " + verifyApiKeyReq.UriPath + ")"
		errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	/* Verify if the ENV matches */
	if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && !contains(apiProductDetails.Environments, verifyApiKeyReq.EnvironmentName) {
		reason := "ENV Validation Failed (" + strings.Join(apiProductDetails.Environments, ", ") + " vs " + verifyApiKeyReq.EnvironmentName + ")"
		errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && !contains(apiProductDetails.Apiproxies, verifyApiKeyReq.ApiProxyName) {
		reason := "Proxy Validation Failed (" + strings.Join(apiProductDetails.Apiproxies, ", ") + " vs " + verifyApiKeyReq.ApiProxyName + ")"
		errorCode := "oauth.v2.InvalidApiKeyForGivenResource"
		return errorResponse(reason, errorCode), errors.New(strconv.Itoa(http.StatusUnauthorized))
	}

	return nil, nil

}

func contains(givenArray []string, searchString string) bool {
	for _, element := range givenArray {
		if element == searchString {
			return true
		}
	}
	return false
}

func enrichAttributes(db apid.DB, tenantId string, clientIdDetails *ClientIdDetails, appDetails *AppDetails, tempDeveloperDetails *DeveloperDetails, apiProductDetails *ApiProductDetails) {
	clientIdAttributes := getKmsAttributes(db, tenantId, clientIdDetails.ClientId)
	developerAttributes := getKmsAttributes(db, tenantId, tempDeveloperDetails.Id)
	appAttributes := getKmsAttributes(db, tenantId, appDetails.Id)
	apiProductAttributes := getKmsAttributes(db, tenantId, apiProductDetails.Id)

	clientIdDetails.Attributes = clientIdAttributes
	appDetails.Attributes = appAttributes
	apiProductDetails.Attributes = apiProductAttributes
	tempDeveloperDetails.Attributes = developerAttributes
}
func getKmsAttributes(db apid.DB, tenantId string, entityId string) []Attribute {

	var attName, attValue sql.NullString
	sql := "select name, value from kms_attributes where tenant_id = $1 and entity_id = $2"
	attributesForQuery := []Attribute{}
	attributes, err := db.Query(sql, tenantId, entityId)
	if err != nil {
		log.Error("Error while fetching attributes for tenant id : %s and entityId : %s", tenantId, entityId, err)
		return attributesForQuery
	}

	for attributes.Next() {
		err := attributes.Scan(
			&attName,
			&attValue,
		)
		if err != nil {
			log.Error("error fetching attributes for entityid ", entityId, err)
		}
		if attName.String != "" {
			att := Attribute{Name: attName.String, Value: attValue.String}
			attributesForQuery = append(attributesForQuery, att)
		}
	}
	log.Debug("attributes returned for query ", sql, " are ", attributesForQuery, tenantId, entityId)
	return attributesForQuery
}

func errorResponse(reason, errorCode string) []byte {
	if errorCode == "SEARCH_INTERNAL_ERROR" {
		log.Error(reason)
	} else {
		log.Debug(reason)
	}
	resp := ErrorResponse{
		ResponseCode:    errorCode,
		ResponseMessage: reason,
	}
	ret, _ := json.Marshal(resp)
	return ret
}

func getApiKeyDetails(db apid.DB, verifyApiKeyReq VerifyApiKeyRequest, cType, tenantId *sql.NullString, tempDeveloperDetails *DeveloperDetails, appDetails *AppDetails, apiProductDetails *ApiProductDetails, clientIdDetails *ClientIdDetails) error {

	var proxies, environments, resources string
	sSql := `
		SELECT
			COALESCE("developer","") as ctype,
			COALESCE(c.tenant_id,""),

			COALESCE(c.status,""),
			COALESCE(c.consumer_secret,""),

			COALESCE(ad.id,"") as dev_id,
			COALESCE(ad.username,"") as dev_username,
			COALESCE(ad.first_name,"") as dev_first_name,
			COALESCE(ad.last_name,"") as dev_last_name,
			COALESCE(ad.email,"") as dev_email,
			COALESCE(ad.status,"") as dev_status,
			COALESCE(ad.created_at,"") as dev_created_at,
			COALESCE(ad.created_by,"") as dev_created_by,
			COALESCE(ad.updated_at,"") as dev_updated_at,
			COALESCE(ad.updated_by,"") as dev_updated_by,

			COALESCE(a.id,"") as app_id,
			COALESCE(a.name,"") as app_name,
			COALESCE(a.access_type,"") as app_access_type,
			COALESCE(a.callback_url,"") as app_callback_url,
			COALESCE(a.display_name,"") as app_display_name,
			COALESCE(a.status,"") as app_status,
			COALESCE(a.app_family,"") as app_app_family,
			COALESCE(a.company_id,"") as app_company_id,
			COALESCE(a.created_at,"") as app_created_at,
			COALESCE(a.created_by,"") as app_created_by,
			COALESCE(a.updated_at,"") as app_updated_at,
			COALESCE(a.updated_by,"") as app_updated_by,

			COALESCE(ap.id,"") as prod_id,
			COALESCE(ap.name,"") as prod_name,
			COALESCE(ap.display_name,"") as prod_display_name,
			COALESCE(ap.quota,"") as prod_quota,
			COALESCE(ap.quota_interval, 0) as prod_quota_interval,
			COALESCE(ap.quota_time_unit,"") as prod_quota_time_unit,
			COALESCE(ap.created_at,"") as prod_created_at,
			COALESCE(ap.created_by,"") as prod_created_by,
			COALESCE(ap.updated_at,"") as prod_updated_at,
			COALESCE(ap.updated_by,"") as prod_updated_by,
			COALESCE(ap.proxies,"") as prod_proxies,
			COALESCE(ap.environments,"") as prod_environments,
			COALESCE(ap.api_resources,"") as prod_resources
		FROM
			KMS_APP_CREDENTIAL AS c
			INNER JOIN KMS_APP AS a
				ON c.app_id = a.id
			INNER JOIN KMS_DEVELOPER AS ad
				ON ad.id = a.developer_id
			INNER JOIN KMS_APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
				ON mp.appcred_id = c.id
			INNER JOIN KMS_API_PRODUCT as ap
				ON ap.id = mp.apiprdt_id
			INNER JOIN KMS_ORGANIZATION AS o
				ON o.tenant_id = c.tenant_id
		WHERE 	(mp.apiprdt_id = ap.id
			AND mp.app_id = a.id
			AND mp.appcred_id = c.id
			AND c.id = $1
			AND o.name = $2)
		UNION ALL
		SELECT
			COALESCE("company","") as ctype,
			COALESCE(c.tenant_id,""),

			COALESCE(c.status,""),
			COALESCE(c.consumer_secret,""),

			COALESCE(ad.id,"") as dev_id,
			COALESCE(ad.display_name,"") as dev_username,
			COALESCE("","") as dev_first_name,
			COALESCE("","") as dev_last_name,
			COALESCE("","") as dev_email,
			COALESCE(ad.status,"") as dev_status,
			COALESCE(ad.created_at,"") as dev_created_at,
			COALESCE(ad.created_by,"") as dev_created_by,
			COALESCE(ad.updated_at,"") as dev_updated_at,
			COALESCE(ad.updated_by,"") as dev_updated_by,

			COALESCE(a.id,"") as app_id,
			COALESCE(a.name,"") as app_name,
			COALESCE(a.access_type,"") as app_access_type,
			COALESCE(a.callback_url,"") as app_callback_url,
			COALESCE(a.display_name,"") as app_display_name,
			COALESCE(a.status,"") as app_status,
			COALESCE(a.app_family,"") as app_app_family,
			COALESCE(a.company_id,"") as app_company_id,
			COALESCE(a.created_at,"") as app_created_at,
			COALESCE(a.created_by,"") as app_created_by,
			COALESCE(a.updated_at,"") as app_updated_at,
			COALESCE(a.updated_by,"") as app_updated_by,

			COALESCE(ap.id,"") as prod_id,
			COALESCE(ap.name,"") as prod_name,
			COALESCE(ap.display_name,"") as prod_display_name,
			COALESCE(ap.quota,"") as prod_quota,
			COALESCE(ap.quota_interval,0) as prod_quota_interval,
			COALESCE(ap.quota_time_unit,"") as prod_quota_time_unit,
			COALESCE(ap.created_at,"") as prod_created_at,
			COALESCE(ap.created_by,"") as prod_created_by,
			COALESCE(ap.updated_at,"") as prod_updated_at,
			COALESCE(ap.updated_by,"") as prod_updated_by,
			COALESCE(ap.proxies,"") as prod_proxies,
			COALESCE(ap.environments,"") as prod_environments,
			COALESCE(ap.api_resources,"") as prod_resources

		FROM
			KMS_APP_CREDENTIAL AS c
			INNER JOIN KMS_APP AS a
				ON c.app_id = a.id
			INNER JOIN KMS_COMPANY AS ad
				ON ad.id = a.company_id
			INNER JOIN KMS_APP_CREDENTIAL_APIPRODUCT_MAPPER as mp
				ON mp.appcred_id = c.id
			INNER JOIN KMS_API_PRODUCT as ap
				ON ap.id = mp.apiprdt_id
			INNER JOIN KMS_ORGANIZATION AS o
				ON o.tenant_id = c.tenant_id
		WHERE   (mp.apiprdt_id = ap.id
			AND mp.app_id = a.id
			AND mp.appcred_id = c.id
			AND c.id = $1
			AND o.name = $2)
	;`

	//cid,csecret,did,dusername,dfirstname,dlastname,demail,dstatus,dcreated_at,dcreated_by,dlast_modified_at,dlast_modified_by, aid,aname,aaccesstype,acallbackurl,adisplay_name,astatus,aappfamily, acompany,acreated_at,acreated_by,alast_modified_at,alast_modified_by,pid,pname,pdisplayname,pquota_limit,pqutoainterval,pquotatimeout,pcreated_at,pcreated_by,plast_modified_at,plast_modified_by sql.NullString

	err := db.QueryRow(sSql, verifyApiKeyReq.Key, verifyApiKeyReq.OrganizationName).
		Scan(
			cType,
			tenantId,
			&clientIdDetails.Status,
			&clientIdDetails.ClientSecret,

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

			&appDetails.Id,
			&appDetails.Name,
			&appDetails.AccessType,
			&appDetails.CallbackUrl,
			&appDetails.DisplayName,
			&appDetails.Status,
			&appDetails.AppFamily,
			&appDetails.Company,
			&appDetails.CreatedAt,
			&appDetails.CreatedBy,
			&appDetails.LastmodifiedAt,
			&appDetails.LastmodifiedBy,

			&apiProductDetails.Id,
			&apiProductDetails.Name,
			&apiProductDetails.DisplayName,
			&apiProductDetails.QuotaLimit,
			&apiProductDetails.QuotaInterval,
			&apiProductDetails.QuotaTimeunit,
			&apiProductDetails.CreatedAt,
			&apiProductDetails.CreatedBy,
			&apiProductDetails.LastmodifiedAt,
			&apiProductDetails.LastmodifiedBy,
			&proxies,
			&environments,
			&resources,
		)

	if err != nil {
		log.Error("error fetching verify apikey details", err)
	}

	if err := json.Unmarshal([]byte(proxies), &apiProductDetails.Apiproxies); err != nil {
		log.Debug("unmarshall error for proxies, performing custom unmarshal ", proxies, err)

		apiProductDetails.Apiproxies = splitMalformedJson(proxies)

	}
	if err := json.Unmarshal([]byte(environments), &apiProductDetails.Environments); err != nil {
		log.Debug("unmarshall error for proxies, performing custom unmarshal ", environments, err)
		apiProductDetails.Environments = splitMalformedJson(environments)

	}
	if err := json.Unmarshal([]byte(resources), &apiProductDetails.Resources); err != nil {
		log.Debug("unmarshall error for proxies, performing custom unmarshal ", resources, err)
		apiProductDetails.Resources = splitMalformedJson(resources)

	}

	if appDetails.CallbackUrl != "" {
		clientIdDetails.RedirectURIs = []string{appDetails.CallbackUrl}
	}

	return err
}

func splitMalformedJson(fjson string) []string {
	var fs []string
	s := strings.TrimPrefix(fjson, "{")
	s = strings.TrimSuffix(s, "}")
	if utf8.RuneCountInString(s) > 0 {
		fs = strings.Split(s, ",")
	}
	return fs
}
