// 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 (
	"encoding/json"
	"github.com/apid/apid-core/util"
	"github.com/apid/apidApiMetadata/common"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

type ApiManagerInterface interface {
	InitAPI()
	HandleRequest(w http.ResponseWriter, r *http.Request)
	verifyAPIKey(verifyApiKeyReq VerifyApiKeyRequest) (*VerifyApiKeySuccessResponse, *common.ErrorResponse)
}

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")

	var returnValue interface{}

	verifyApiKeyReq, err := validateRequest(r.Body, w)
	if err != nil {
		errorResponse, jsonErr := json.Marshal(errorResponse("Bad_REQUEST", err.Error(), http.StatusBadRequest))
		if jsonErr != nil {
			w.WriteHeader(http.StatusInternalServerError)
			w.Write([]byte(jsonErr.Error()))
		}
		w.WriteHeader(http.StatusBadRequest)
		w.Write(errorResponse)
		return
	}

	verifyApiKeyResponse, errorResponse := a.verifyAPIKey(verifyApiKeyReq)

	if errorResponse != nil {
		setResponseHeader(errorResponse, w)
		returnValue = errorResponse
	} else {
		returnValue = verifyApiKeyResponse
	}
	b, _ := json.Marshal(returnValue)
	log.Debugf("handleVerifyAPIKey result %s", b)
	w.Write(b)

}

func setResponseHeader(errorResponse *common.ErrorResponse, w http.ResponseWriter) {
	if errorResponse.StatusCode != 0 {
		w.WriteHeader(errorResponse.StatusCode)
	} else {
		w.WriteHeader(http.StatusInternalServerError)
	}
}

func validateRequest(requestBody io.ReadCloser, w http.ResponseWriter) (VerifyApiKeyRequest, error) {
	defer requestBody.Close()
	// 1. read request boby
	var verifyApiKeyReq VerifyApiKeyRequest
	body, err := ioutil.ReadAll(requestBody)
	if err != nil {
		return verifyApiKeyReq, err
	}
	log.Debug("request body: ", string(body))
	// 2. umarshall json to struct
	err = json.Unmarshal(body, &verifyApiKeyReq)
	if err != nil {
		return verifyApiKeyReq, err
	}
	log.Debug(verifyApiKeyReq)

	// 2. verify params
	if isValid, err := verifyApiKeyReq.validate(); !isValid {
		return verifyApiKeyReq, err
	}
	return verifyApiKeyReq, nil
}

// returns []byte to be written to client
func (apiM ApiManager) verifyAPIKey(verifyApiKeyReq VerifyApiKeyRequest) (*VerifyApiKeySuccessResponse, *common.ErrorResponse) {

	dataWrapper := VerifyApiKeyRequestResponseDataWrapper{
		verifyApiKeyRequest: verifyApiKeyReq,
	}
	dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId = verifyApiKeyReq.Key
	dataWrapper.verifyApiKeySuccessResponse.Environment = verifyApiKeyReq.EnvironmentName

	err := apiM.DbMan.getApiKeyDetails(&dataWrapper)

	switch {
	case err != nil && err.Error() == "InvalidApiKey":
		reason := "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode := "oauth.v2.InvalidApiKey"
		errResponse := errorResponse(reason, errorCode, http.StatusOK)
		return nil, &errResponse

	case err != nil:
		reason := err.Error()
		errorCode := "SEARCH_INTERNAL_ERROR"
		errResponse := errorResponse(reason, errorCode, http.StatusInternalServerError)
		return nil, &errResponse
	}

	dataWrapper.verifyApiKeySuccessResponse.ApiProduct = shortListApiProduct(dataWrapper.apiProducts, verifyApiKeyReq)
	/*
	 * Perform all validations
	 */
	errResponse := apiM.performValidations(dataWrapper)
	if errResponse != nil {
		return nil, errResponse
	}

	apiM.enrichAttributes(&dataWrapper)

	setDevOrCompanyInResponseBasedOnCtype(dataWrapper.ctype, dataWrapper.tempDeveloperDetails, &dataWrapper.verifyApiKeySuccessResponse)

	return &dataWrapper.verifyApiKeySuccessResponse, nil
}

func setDevOrCompanyInResponseBasedOnCtype(ctype string, tempDeveloperDetails DeveloperDetails, response *VerifyApiKeySuccessResponse) {
	if ctype == "developer" {
		response.Developer = tempDeveloperDetails
	} else {
		response.Company = CompanyDetails{
			Id:             tempDeveloperDetails.Id,
			Name:           tempDeveloperDetails.FirstName,
			DisplayName:    tempDeveloperDetails.UserName,
			Status:         tempDeveloperDetails.Status,
			CreatedAt:      tempDeveloperDetails.CreatedAt,
			CreatedBy:      tempDeveloperDetails.CreatedBy,
			LastmodifiedAt: tempDeveloperDetails.LastmodifiedAt,
			LastmodifiedBy: tempDeveloperDetails.LastmodifiedBy,
			Attributes:     tempDeveloperDetails.Attributes,
		}
	}
}

func shortListApiProduct(details []ApiProductDetails, verifyApiKeyReq VerifyApiKeyRequest) ApiProductDetails {
	var bestMathcedProduct ApiProductDetails
	rankedProducts := make([][]ApiProductDetails, 2)

	for _, apiProd := range details {
		if len(apiProd.Resources) == 0 || validatePath(apiProd.Resources, verifyApiKeyReq.UriPath) {
			if len(apiProd.Apiproxies) == 0 || util.Contains(apiProd.Apiproxies, verifyApiKeyReq.ApiProxyName) {
				if len(apiProd.Environments) == 0 || util.Contains(apiProd.Environments, verifyApiKeyReq.EnvironmentName) {
					bestMathcedProduct = apiProd
					return bestMathcedProduct
					// set rank 1 or just return
				} else {
					// set rank to 2
					rankedProducts[0] = append(rankedProducts[0], apiProd)
				}
			} else {
				// set rank to 3,
				rankedProducts[1] = append(rankedProducts[1], apiProd)
			}
		}
	}

	if len(rankedProducts[0]) > 0 {
		return rankedProducts[0][0]
	}

	if len(rankedProducts[1]) > 0 {
		return rankedProducts[1][0]
	}

	return bestMathcedProduct

}

func (apiM ApiManager) performValidations(dataWrapper VerifyApiKeyRequestResponseDataWrapper) *common.ErrorResponse {
	clientIdDetails := dataWrapper.verifyApiKeySuccessResponse.ClientId
	verifyApiKeyReq := dataWrapper.verifyApiKeyRequest
	appDetails := dataWrapper.verifyApiKeySuccessResponse.App
	tempDeveloperDetails := dataWrapper.tempDeveloperDetails
	cType := dataWrapper.ctype
	apiProductDetails := dataWrapper.verifyApiKeySuccessResponse.ApiProduct
	var reason, errorCode string

	if !strings.EqualFold("APPROVED", clientIdDetails.Status) {
		reason = "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode = "oauth.v2.ApiKeyNotApproved"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	if !strings.EqualFold("APPROVED", appDetails.Status) {
		reason = "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode = "keymanagement.service.invalid_client-app_not_approved"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	if !strings.EqualFold("ACTIVE", tempDeveloperDetails.Status) {
		reason = "API Key verify failed for (" + verifyApiKeyReq.Key + ", " + verifyApiKeyReq.OrganizationName + ")"
		errorCode = "keymanagement.service.DeveloperStatusNotActive"
		if cType == "company" {
			errorCode = "keymanagement.service.CompanyStatusNotActive"
		}
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	if dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id == "" {
		reason = "Path Validation Failed. Product not resolved"
		errorCode = "oauth.v2.InvalidApiKeyForGivenResource"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	result := len(apiProductDetails.Resources) == 0 || validatePath(apiProductDetails.Resources, verifyApiKeyReq.UriPath)
	if !result {
		reason = "Path Validation Failed (" + strings.Join(apiProductDetails.Resources, ", ") + " vs " + verifyApiKeyReq.UriPath + ")"
		errorCode = "oauth.v2.InvalidApiKeyForGivenResource"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && (len(apiProductDetails.Apiproxies) > 0 && !util.Contains(apiProductDetails.Apiproxies, verifyApiKeyReq.ApiProxyName)) {
		reason = "Proxy Validation Failed (" + strings.Join(apiProductDetails.Apiproxies, ", ") + " vs " + verifyApiKeyReq.ApiProxyName + ")"
		errorCode = "oauth.v2.InvalidApiKeyForGivenResource"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}
	/* Verify if the ENV matches */
	if verifyApiKeyReq.ValidateAgainstApiProxiesAndEnvs && (len(apiProductDetails.Environments) > 0 && !util.Contains(apiProductDetails.Environments, verifyApiKeyReq.EnvironmentName)) {
		reason = "ENV Validation Failed (" + strings.Join(apiProductDetails.Environments, ", ") + " vs " + verifyApiKeyReq.EnvironmentName + ")"
		errorCode = "oauth.v2.InvalidApiKeyForGivenResource"
		log.Debug("Validation error occoured ", errorCode, " ", reason)
		ee := errorResponse(reason, errorCode, http.StatusOK)
		return &ee
	}

	return nil

}

func (a *ApiManager) enrichAttributes(dataWrapper *VerifyApiKeyRequestResponseDataWrapper) {

	attributeMap := a.DbMan.GetKmsAttributes(dataWrapper.tenant_id, dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId, dataWrapper.tempDeveloperDetails.Id, dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id, dataWrapper.verifyApiKeySuccessResponse.App.Id)

	clientIdAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.ClientId.ClientId]
	developerAttributes := attributeMap[dataWrapper.tempDeveloperDetails.Id]
	appAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.App.Id]
	apiProductAttributes := attributeMap[dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Id]

	dataWrapper.verifyApiKeySuccessResponse.ClientId.Attributes = clientIdAttributes
	dataWrapper.verifyApiKeySuccessResponse.App.Attributes = appAttributes
	dataWrapper.verifyApiKeySuccessResponse.ApiProduct.Attributes = apiProductAttributes
	dataWrapper.tempDeveloperDetails.Attributes = developerAttributes
}

func errorResponse(reason, errorCode string, statusCode int) common.ErrorResponse {
	if errorCode == "SEARCH_INTERNAL_ERROR" {
		log.Error(reason)
	} else {
		log.Debug(reason)
	}
	resp := common.ErrorResponse{
		ResponseCode:    errorCode,
		ResponseMessage: reason,
		StatusCode:      statusCode,
	}
	return resp
}
