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

import (
	"encoding/json"
	"fmt"
	"github.com/apid/apidVerifyApiKey/common"
	"net/http"
	"strconv"
	"strings"
)

const (
	AccessEntityPath         = "/entities"
	EndpointApp              = "/apps"
	EndpointApiProduct       = "/apiproducts"
	EndpointCompany          = "/companies"
	EndpointCompanyDeveloper = "/companydevelopers"
	EndpointDeveloper        = "/developers"
	EndpointAppCredentials   = "/appcredentials"
)

const (
	IdentifierAppId          = "appid"
	IdentifierApiProductName = "apiproductname"
	IdentifierAppName        = "appname"
	IdentifierApiResource    = "apiresource"
	IdentifierDeveloperId    = "developerid"
	IdentifierDeveloperEmail = "developeremail"
	IdentifierConsumerKey    = "consumerkey"
	IdentifierCompanyName    = "companyname"
	IdentifierOrganization   = "organization"
)

const (
	TypeDeveloper   = "developer"
	TypeCompany     = "company"
	TypeApp         = "app"
	TypeConsumerKey = "consumerkey"
)

const (
	AppTypeDeveloper = "DEVELOPER"
	AppTypeCompany   = "COMPANY"
)

const (
	StatusApproved = "APPROVED"
	StatusRevoked  = "REVOKED"
	StatusExpired  = "EXPIRED"
)

var (
	Identifiers = map[string]bool{
		"appid":          true,
		"apiproductname": true,
		"appname":        true,
		"apiresource":    true,
		"developerid":    true,
		"companyname":    true,
		"developeremail": true,
		"consumerkey":    true,
	}

	ErrInvalidPar = &common.ErrorResponse{
		ResponseCode:    strconv.Itoa(INVALID_PARAMETERS),
		ResponseMessage: "invalid identifiers",
		StatusCode:      http.StatusBadRequest,
	}

	ErrNotFound = &common.ErrorResponse{
		ResponseCode:    strconv.Itoa(NOT_FOUND),
		ResponseMessage: "Resource Not Found",
		StatusCode:      http.StatusNotFound,
	}

	IdentifierTree = map[string]map[string][]string{
		EndpointApiProduct: {
			IdentifierApiProductName: {},
			IdentifierAppId:          {IdentifierApiResource},
			IdentifierAppName:        {IdentifierApiResource, IdentifierDeveloperEmail, IdentifierDeveloperId, IdentifierCompanyName},
			IdentifierConsumerKey:    {IdentifierApiResource},
		},
		EndpointApp: {
			IdentifierAppId:       {},
			IdentifierAppName:     {IdentifierDeveloperEmail, IdentifierDeveloperId, IdentifierCompanyName},
			IdentifierConsumerKey: {},
		},
		EndpointCompany: {
			IdentifierAppId:       {},
			IdentifierCompanyName: {},
			IdentifierConsumerKey: {},
		},
		EndpointCompanyDeveloper: {
			IdentifierCompanyName: {},
		},
		EndpointAppCredentials: {
			IdentifierConsumerKey: {},
		},
		EndpointDeveloper: {
			IdentifierDeveloperEmail: {},
			IdentifierAppId:          {},
			IdentifierDeveloperId:    {},
			IdentifierConsumerKey:    {},
		},
	}
)

const (
	INVALID_PARAMETERS = iota
	DB_ERROR
	DATA_ERROR
	NOT_FOUND
)

type ApiManager struct {
	DbMan            DbManagerInterface
	AccessEntityPath string
	apiInitialized   bool
}

func (a *ApiManager) InitAPI() {
	if a.apiInitialized {
		return
	}
	services.API().HandleFunc(a.AccessEntityPath+EndpointApp, a.HandleApps).Methods("GET")
	services.API().HandleFunc(a.AccessEntityPath+EndpointApiProduct, a.HandleApiProducts).Methods("GET")
	services.API().HandleFunc(a.AccessEntityPath+EndpointCompany, a.HandleCompanies).Methods("GET")
	services.API().HandleFunc(a.AccessEntityPath+EndpointCompanyDeveloper, a.HandleCompanyDevelopers).Methods("GET")
	services.API().HandleFunc(a.AccessEntityPath+EndpointDeveloper, a.HandleDevelopers).Methods("GET")
	services.API().HandleFunc(a.AccessEntityPath+EndpointAppCredentials, a.HandleAppCredentials).Methods("GET")
	a.apiInitialized = true
	log.Debug("API endpoints initialized")
}

func (a *ApiManager) HandleApps(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	res, errRes := a.getApp(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(res, w, r)
}

func (a *ApiManager) HandleApiProducts(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	details, errRes := a.getApiProduct(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(details, w, r)
}

func (a *ApiManager) HandleCompanies(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	details, errRes := a.getCompany(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(details, w, r)
}

func (a *ApiManager) HandleCompanyDevelopers(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	details, errRes := a.getCompanyDeveloper(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(details, w, r)
}
func (a *ApiManager) HandleDevelopers(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	details, errRes := a.getDeveloper(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(details, w, r)
}

func (a *ApiManager) HandleAppCredentials(w http.ResponseWriter, r *http.Request) {
	ids, org, err := extractIdentifiers(r.URL.Query())
	if err != nil {
		common.WriteError(w, err.Error(), INVALID_PARAMETERS, http.StatusBadRequest)
	}
	details, errRes := a.getAppCredential(org, ids)
	if errRes != nil {
		w.WriteHeader(errRes.StatusCode)
		writeJson(errRes, w, r)
		return
	}
	writeJson(details, w, r)
}

func extractIdentifiers(pars map[string][]string) (map[string]string, string, error) {
	m := make(map[string]string)
	orgs := pars[IdentifierOrganization]
	if len(orgs) == 0 {
		return nil, "", fmt.Errorf("no org specified")
	}
	org := orgs[0]
	for k, v := range pars {
		k = strings.ToLower(k)
		if Identifiers[k] {
			if len(v) == 1 {
				m[k] = v[0]
			} else {
				return nil, org, fmt.Errorf("each identifier must have only 1 value")
			}
		}
	}
	return m, org, nil
}

func (a *ApiManager) getCompanyDeveloper(org string, ids map[string]string) (*CompanyDevelopersSuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointCompanyDeveloper, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	devs, err := a.DbMan.GetCompanyDevelopers(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getCompanyDeveloper: %v", err)
		return nil, newDbError(err)
	}

	if len(devs) == 0 {
		return nil, ErrNotFound
	}

	var details []*CompanyDeveloperDetails
	for _, dev := range devs {
		comName, err := a.DbMan.GetComNames(dev.CompanyId, TypeCompany)
		if err != nil || len(comName) == 0 {
			log.Errorf("getCompanyDeveloper: %v", err)
			return nil, newDbError(err)
		}
		email, err := a.DbMan.GetDevEmailByDevId(dev.DeveloperId)
		if err != nil {
			log.Errorf("getCompanyDeveloper: %v", err)
			return nil, newDbError(err)
		}
		detail := makeComDevDetails(&dev, comName[0], email)
		details = append(details, detail)
	}
	return &CompanyDevelopersSuccessResponse{
		CompanyDevelopers:      details,
		Organization:           org,
		PrimaryIdentifierType:  priKey,
		PrimaryIdentifierValue: priVal,
	}, nil
}

func (a *ApiManager) getDeveloper(org string, ids map[string]string) (*DeveloperSuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointDeveloper, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	devs, err := a.DbMan.GetDevelopers(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getDeveloper: %v", err)
		return nil, newDbError(err)
	}

	if len(devs) == 0 {
		return nil, ErrNotFound
	}
	dev := &devs[0]

	attrs := a.DbMan.GetKmsAttributes(dev.TenantId, dev.Id)[dev.Id]
	comNames, err := a.DbMan.GetComNames(dev.Id, TypeDeveloper)
	if err != nil {
		log.Errorf("getDeveloper: %v", err)
		return nil, newDbError(err)
	}
	appNames, err := a.DbMan.GetAppNames(dev.Id, TypeDeveloper)
	if err != nil {
		log.Errorf("getDeveloper: %v", err)
		return nil, newDbError(err)
	}
	details := makeDevDetails(dev, appNames, comNames, attrs)
	return &DeveloperSuccessResponse{
		Developer:              details,
		Organization:           org,
		PrimaryIdentifierType:  priKey,
		PrimaryIdentifierValue: priVal,
	}, nil
}

func (a *ApiManager) getCompany(org string, ids map[string]string) (*CompanySuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointCompany, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	coms, err := a.DbMan.GetCompanies(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getCompany: %v", err)
		return nil, newDbError(err)
	}

	if len(coms) == 0 {
		return nil, ErrNotFound
	}
	com := &coms[0]

	attrs := a.DbMan.GetKmsAttributes(com.TenantId, com.Id)[com.Id]
	appNames, err := a.DbMan.GetAppNames(com.Id, TypeCompany)
	if err != nil {
		log.Errorf("getCompany: %v", err)
		return nil, newDbError(err)
	}
	details := makeCompanyDetails(com, appNames, attrs)
	return &CompanySuccessResponse{
		Company:                details,
		Organization:           org,
		PrimaryIdentifierType:  priKey,
		PrimaryIdentifierValue: priVal,
	}, nil
}

func (a *ApiManager) getApiProduct(org string, ids map[string]string) (*ApiProductSuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointApiProduct, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	prods, err := a.DbMan.GetApiProducts(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getApiProduct: %v", err)
		return nil, newDbError(err)
	}

	var attrs []common.Attribute
	if len(prods) == 0 {
		return nil, ErrNotFound
	}
	prod := &prods[0]
	attrs = a.DbMan.GetKmsAttributes(prod.TenantId, prod.Id)[prod.Id]
	details, errRes := makeApiProductDetails(prod, attrs)
	if errRes != nil {
		return nil, errRes
	}

	return &ApiProductSuccessResponse{
		ApiProduct:               details,
		Organization:             org,
		PrimaryIdentifierType:    priKey,
		PrimaryIdentifierValue:   priVal,
		SecondaryIdentifierType:  secKey,
		SecondaryIdentifierValue: secVal,
	}, nil
}

func (a *ApiManager) getAppCredential(org string, ids map[string]string) (*AppCredentialSuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointApiProduct, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	appCreds, err := a.DbMan.GetAppCredentials(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getAppCredential: %v", err)
		return nil, newDbError(err)
	}

	if len(appCreds) == 0 {
		return nil, ErrNotFound
	}
	appCred := &appCreds[0]
	attrs := a.DbMan.GetKmsAttributes(appCred.TenantId, appCred.Id)[appCred.Id]
	apps, err := a.DbMan.GetApps(org, IdentifierAppId, appCred.AppId, "", "")
	if err != nil {
		log.Errorf("getAppCredential: %v", err)
		return nil, newDbError(err)
	}

	if len(apps) == 0 {
		log.Errorf("getAppCredential: No App with id=%v", appCred.AppId)
		return &AppCredentialSuccessResponse{
			AppCredential: nil,
			Organization:  org,
		}, nil
	}
	app := &apps[0]
	cd, errRes := a.getCredDetails(appCred, app.Status)
	if errRes != nil {
		return nil, errRes
	}
	devStatus := ""
	if app.DeveloperId != "" {
		devStatus, err = a.DbMan.GetStatus(app.DeveloperId, AppTypeDeveloper)
		if err != nil {
			log.Errorf("getAppCredential error get status: %v", err)
			return nil, newDbError(err)
		}
	}
	cks := makeConsumerKeyStatusDetails(app, cd, devStatus)
	//TODO: redirectUris
	details := makeAppCredentialDetails(appCred, cks, []string{app.CallbackUrl}, attrs)
	return &AppCredentialSuccessResponse{
		AppCredential:          details,
		Organization:           org,
		PrimaryIdentifierType:  priKey,
		PrimaryIdentifierValue: priVal,
	}, nil
}

func (a *ApiManager) getApp(org string, ids map[string]string) (*AppSuccessResponse, *common.ErrorResponse) {
	valid, keyVals := parseIdentifiers(EndpointApp, ids)
	if !valid {
		return nil, ErrInvalidPar
	}
	priKey, priVal, secKey, secVal := keyVals[0], keyVals[1], keyVals[2], keyVals[3]

	apps, err := a.DbMan.GetApps(org, priKey, priVal, secKey, secVal)
	if err != nil {
		log.Errorf("getApp: %v", err)
		return nil, newDbError(err)
	}

	var app *common.App
	var attrs []common.Attribute

	if len(apps) == 0 {
		return nil, ErrNotFound
	}

	app = &apps[0]
	attrs = a.DbMan.GetKmsAttributes(app.TenantId, app.Id)[app.Id]
	prods, err := a.DbMan.GetApiProductNames(app.Id, TypeApp)
	if err != nil {
		log.Errorf("getApp error getting productNames: %v", err)
		return nil, newDbError(err)
	}
	parStatus, err := a.DbMan.GetStatus(app.ParentId, app.Type)
	if err != nil {
		log.Errorf("getApp error getting parent status: %v", err)
		return nil, newDbError(err)
	}
	creds, err := a.DbMan.GetAppCredentials(org, IdentifierAppId, app.Id, "", "")
	if err != nil {
		log.Errorf("getApp error getting parent status: %v", err)
		return nil, newDbError(err)
	}
	var credDetails []*CredentialDetails
	for _, cred := range creds {
		detail, errRes := a.getCredDetails(&cred, app.Status)
		if errRes != nil {
			return nil, errRes
		}
		credDetails = append(credDetails, detail)
	}

	details, errRes := makeAppDetails(app, parStatus, prods, credDetails, attrs)
	if errRes != nil {
		return nil, errRes
	}
	return &AppSuccessResponse{
		App:                      details,
		Organization:             org,
		PrimaryIdentifierType:    priKey,
		PrimaryIdentifierValue:   priVal,
		SecondaryIdentifierType:  secKey,
		SecondaryIdentifierValue: secVal,
	}, nil
}

func makeConsumerKeyStatusDetails(app *common.App, c *CredentialDetails, devStatus string) *ConsumerKeyStatusDetails {
	return &ConsumerKeyStatusDetails{
		AppCredential:   c,
		AppID:           c.AppID,
		AppName:         app.Name,
		AppStatus:       app.Status,
		AppType:         app.Type,
		DeveloperID:     app.DeveloperId,
		DeveloperStatus: devStatus,
		IsValidKey:      strings.EqualFold(c.Status, StatusApproved),
	}
}

func makeAppCredentialDetails(ac *common.AppCredential, cks *ConsumerKeyStatusDetails, redirectUrl []string, attrs []common.Attribute) *AppCredentialDetails {
	return &AppCredentialDetails{
		AppID:             ac.AppId,
		AppName:           cks.AppName,
		Attributes:        attrs,
		ConsumerKey:       ac.Id,
		ConsumerKeyStatus: cks,
		ConsumerSecret:    ac.ConsumerSecret,
		DeveloperID:       cks.DeveloperID,
		RedirectUris:      redirectUrl, //TODO
		Scopes:            common.JsonToStringArray(ac.Scopes),
		Status:            ac.Status,
	}
}

func makeApiProductDetails(prod *common.ApiProduct, attrs []common.Attribute) (*ApiProductDetails, *common.ErrorResponse) {
	var a *ApiProductDetails
	if prod != nil {
		var quotaLimit int
		var err error
		if prod.Quota != "" {
			quotaLimit, err = strconv.Atoi(prod.Quota)
			if err != nil {
				return nil, newDataError(err)
			}
		}

		a = &ApiProductDetails{
			ApiProxies:     common.JsonToStringArray(prod.Proxies),
			ApiResources:   common.JsonToStringArray(prod.ApiResources),
			ApprovalType:   prod.ApprovalType,
			Attributes:     attrs,
			CreatedAt:      prod.CreatedAt,
			CreatedBy:      prod.CreatedBy,
			Description:    prod.Description,
			DisplayName:    prod.DisplayName,
			Environments:   common.JsonToStringArray(prod.Environments),
			ID:             prod.Id,
			LastModifiedAt: prod.UpdatedAt,
			LastModifiedBy: prod.UpdatedBy,
			Name:           prod.Name,
			QuotaInterval:  prod.QuotaInterval,
			QuotaLimit:     int64(quotaLimit),
			QuotaTimeUnit:  prod.QuotaTimeUnit,
			Scopes:         common.JsonToStringArray(prod.Scopes),
		}
	} else {
		a = new(ApiProductDetails)
	}
	return a, nil
}

func makeAppDetails(app *common.App, parentStatus string, prods []string, creds []*CredentialDetails, attrs []common.Attribute) (*AppDetails, *common.ErrorResponse) {
	var a *AppDetails
	if app != nil {
		a = &AppDetails{
			AccessType:      app.AccessType,
			ApiProducts:     prods,
			AppCredentials:  creds,
			AppFamily:       app.AppFamily,
			AppParentID:     app.ParentId,
			AppParentStatus: parentStatus,
			AppType:         app.Type,
			Attributes:      attrs,
			CallbackUrl:     app.CallbackUrl,
			CreatedAt:       app.CreatedAt,
			CreatedBy:       app.CreatedBy,
			DisplayName:     app.DisplayName,
			Id:              app.Id,
			KeyExpiresIn:    "", //TODO
			LastModifiedAt:  app.UpdatedAt,
			LastModifiedBy:  app.UpdatedBy,
			Name:            app.Name,
			Scopes:          []string{}, //TODO
			Status:          app.Status,
		}
	} else {
		a = new(AppDetails)
	}
	return a, nil
}

func makeCompanyDetails(com *common.Company, appNames []string, attrs []common.Attribute) *CompanyDetails {
	return &CompanyDetails{
		Apps:           appNames,
		Attributes:     attrs,
		CreatedAt:      com.CreatedAt,
		CreatedBy:      com.CreatedBy,
		DisplayName:    com.DisplayName,
		ID:             com.Id,
		LastModifiedAt: com.UpdatedAt,
		LastModifiedBy: com.UpdatedBy,
		Name:           com.Name,
		Status:         com.Status,
	}
}

func makeDevDetails(dev *common.Developer, appNames []string, comNames []string, attrs []common.Attribute) *DeveloperDetails {
	return &DeveloperDetails{
		Apps:           appNames,
		Attributes:     attrs,
		Companies:      comNames,
		CreatedAt:      dev.CreatedAt,
		CreatedBy:      dev.CreatedBy,
		Email:          dev.Email,
		FirstName:      dev.FirstName,
		ID:             dev.Id,
		LastModifiedAt: dev.UpdatedAt,
		LastModifiedBy: dev.UpdatedBy,
		LastName:       dev.LastName,
		Password:       dev.Password,
		Status:         dev.Status,
		UserName:       dev.UserName,
	}
}

func makeComDevDetails(comDev *common.CompanyDeveloper, comName, devEmail string) *CompanyDeveloperDetails {
	return &CompanyDeveloperDetails{
		CompanyName:    comName,
		CreatedAt:      comDev.CreatedAt,
		CreatedBy:      comDev.CreatedBy,
		DeveloperEmail: devEmail,
		LastModifiedAt: comDev.UpdatedAt,
		LastModifiedBy: comDev.UpdatedBy,
		Roles:          common.JsonToStringArray(comDev.Roles),
	}
}

func (a *ApiManager) getCredDetails(cred *common.AppCredential, appStatus string) (*CredentialDetails, *common.ErrorResponse) {

	refs, err := a.DbMan.GetApiProductNames(cred.Id, TypeConsumerKey)
	if err != nil {
		log.Errorf("Error when getting product reference list")
		return nil, newDbError(err)
	}
	return &CredentialDetails{
		ApiProductReferences: refs,
		AppID:                cred.AppId,
		AppStatus:            appStatus,
		Attributes:           a.DbMan.GetKmsAttributes(cred.TenantId, cred.Id)[cred.Id],
		ConsumerKey:          cred.Id,
		ConsumerSecret:       cred.ConsumerSecret,
		ExpiresAt:            cred.ExpiresAt,
		IssuedAt:             cred.IssuedAt,
		MethodType:           cred.MethodType,
		Scopes:               common.JsonToStringArray(cred.Scopes),
		Status:               cred.Status,
	}, nil
}

func parseIdentifiers(endpoint string, ids map[string]string) (valid bool, keyVals []string) {
	if len(ids) > 2 {
		return false, nil
	}
	if m := IdentifierTree[endpoint]; m != nil {
		for key, val := range ids {
			if m[key] != nil {
				keyVals = append(keyVals, key, val)
				for _, id := range m[key] {
					if ids[id] != "" {
						keyVals = append(keyVals, id, ids[id])
						return true, keyVals
					}
				}
				if len(ids) == 2 {
					return false, nil
				}
				keyVals = append(keyVals, "", "")
				return true, keyVals
			}
		}
	}
	return false, nil
}

func newDbError(err error) *common.ErrorResponse {
	return &common.ErrorResponse{
		ResponseCode:    strconv.Itoa(DB_ERROR),
		ResponseMessage: err.Error(),
		StatusCode:      http.StatusInternalServerError,
	}
}

func newDataError(err error) *common.ErrorResponse {
	return &common.ErrorResponse{
		ResponseCode:    strconv.Itoa(DATA_ERROR),
		ResponseMessage: err.Error(),
		StatusCode:      http.StatusInternalServerError,
	}
}

func writeJson(obj interface{}, w http.ResponseWriter, r *http.Request) {
	bytes, err := json.Marshal(obj)
	if err != nil {
		log.Error("unable to marshal errorResponse: " + err.Error())
		w.Write([]byte("unable to marshal errorResponse: " + err.Error()))
	} else {
		w.Header().Set("Content-Type", "application/json")
		w.Write(bytes)
	}
}
