package tc

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

import (
	"database/sql"
	"errors"
	"fmt"
	"strconv"
	"strings"

	"github.com/apache/trafficcontrol/lib/go-log"
	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
	"github.com/apache/trafficcontrol/lib/go-util"

	validation "github.com/go-ozzo/ozzo-validation"
	"github.com/lib/pq"
)

// These are the valid values for the Type property of a Profile. No other
// values will be accepted, and these are not configurable.
const (
	CacheServerProfileType     = "ATS_PROFILE"
	DeliveryServiceProfileType = "DS_PROFILE"
	ElasticSearchProfileType   = "ES_PROFILE"
	GroveProfileType           = "GROVE_PROFILE"
	InfluxdbProfileType        = "INFLUXDB_PROFILE"
	KafkaProfileType           = "KAFKA_PROFILE"
	LogstashProfileType        = "LOGSTASH_PROFILE"
	OriginProfileType          = "ORG_PROFILE"
	// RiakProfileType is the type of a Profile used on the legacy RiakKV system
	// which used to be used as a back-end for Traffic Vault.
	//
	// Deprecated: Support for Riak as a Traffic Vault back-end is being dropped
	// in the near future. Profiles of type UnknownProfileType should be used on
	// PostgreSQL database servers instead.
	RiakProfileType           = "RIAK_PROFILE"
	SplunkProfileType         = "SPLUNK_PROFILE"
	TrafficMonitorProfileType = "TM_PROFILE"
	TrafficPortalProfileType  = "TP_PROFILE"
	TrafficRouterProfileType  = "TR_PROFILE"
	TrafficStatsProfileType   = "TS_PROFILE"
	UnkownProfileType         = "UNK_PROFILE"
)

// ProfilesResponse is a list of profiles returned by GET requests.
type ProfilesResponse struct {
	Response []Profile `json:"response"`
	Alerts
}

// ProfileResponse is a single Profile Response for Update and Create to depict what changed
// swagger:response ProfileResponse
// in: body
type ProfileResponse struct {
	// in: body
	Response Profile `json:"response"`
	Alerts
}

// A Profile represents a set of configuration for a server or Delivery Service
// which may be reused to allow sharing configuration across the objects to
// which it is assigned.
type Profile struct {
	ID              int                 `json:"id" db:"id"`
	LastUpdated     TimeNoMod           `json:"lastUpdated"`
	Name            string              `json:"name"`
	Parameter       string              `json:"param"`
	Description     string              `json:"description"`
	CDNName         string              `json:"cdnName"`
	CDNID           int                 `json:"cdn"`
	RoutingDisabled bool                `json:"routingDisabled"`
	Type            string              `json:"type"`
	Parameters      []ParameterNullable `json:"params,omitempty"`
}

// ProfileNullable is exactly the same as Profile except that its fields are
// reference values, so they may be nil.
type ProfileNullable struct {
	ID              *int                `json:"id" db:"id"`
	LastUpdated     *TimeNoMod          `json:"lastUpdated" db:"last_updated"`
	Name            *string             `json:"name" db:"name"`
	Description     *string             `json:"description" db:"description"`
	CDNName         *string             `json:"cdnName" db:"cdn_name"`
	CDNID           *int                `json:"cdn" db:"cdn"`
	RoutingDisabled *bool               `json:"routingDisabled" db:"routing_disabled"`
	Type            *string             `json:"type" db:"type"`
	Parameters      []ParameterNullable `json:"params,omitempty"`
}

// ProfileCopy contains details about the profile created from an existing profile.
type ProfileCopy struct {
	ID           int    `json:"id"`
	Name         string `json:"name"`
	ExistingID   int    `json:"idCopyFrom"`
	ExistingName string `json:"profileCopyFrom"`
	Description  string `json:"description"`
}

// ProfileCopyResponse represents the Traffic Ops API's response when a Profile
// is copied.
type ProfileCopyResponse struct {
	Response ProfileCopy `json:"response"`
	Alerts
}

// ProfileExportImportNullable is an object of the form used by Traffic Ops
// to represent exported and imported profiles.
type ProfileExportImportNullable struct {
	Name        *string `json:"name"`
	Description *string `json:"description"`
	CDNName     *string `json:"cdn"`
	Type        *string `json:"type"`
}

// ProfileExportResponse is an object of the form used by Traffic Ops
// to represent exported profile response.
type ProfileExportResponse struct {
	// Parameters associated to the profile
	//
	Profile ProfileExportImportNullable `json:"profile"`

	// Parameters associated to the profile
	//
	Parameters []ProfileExportImportParameterNullable `json:"parameters"`

	Alerts
}

// ProfileImportRequest is an object of the form used by Traffic Ops
// to represent a request to import a profile.
type ProfileImportRequest struct {
	// Parameters associated to the profile
	//
	Profile ProfileExportImportNullable `json:"profile"`

	// Parameters associated to the profile
	//
	Parameters []ProfileExportImportParameterNullable `json:"parameters"`
}

// ProfileImportResponse is an object of the form used by Traffic Ops
// to represent a response from importing a profile.
type ProfileImportResponse struct {
	Response ProfileImportResponseObj `json:"response"`
	Alerts
}

// ProfileImportResponseObj contains data about the profile being imported.
type ProfileImportResponseObj struct {
	ProfileExportImportNullable
	ID *int `json:"id"`
}

// Validate validates an profile import request, implementing the
// github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api.ParseValidator
// interface.
func (profileImport *ProfileImportRequest) Validate(tx *sql.Tx) error {

	profile := profileImport.Profile

	// Profile fields are valid
	errs := tovalidate.ToErrors(validation.Errors{
		"name": validation.Validate(profile.Name, validation.By(
			func(value interface{}) error {
				name, ok := value.(*string)
				if !ok {
					return fmt.Errorf("wrong type, need: string, got: %T", value)
				}
				if name == nil || *name == "" {
					return errors.New("required and cannot be blank")
				}
				if strings.Contains(*name, " ") {
					return errors.New("cannot contain spaces")
				}
				return nil
			},
		)),
		"description": validation.Validate(profile.Description, validation.Required),
		"cdnName":     validation.Validate(profile.CDNName, validation.Required),
		"type":        validation.Validate(profile.Type, validation.Required),
	})

	// Validate CDN exist
	if profile.CDNName != nil {
		if ok, err := CDNExistsByName(*profile.CDNName, tx); err != nil {
			errString := fmt.Sprintf("checking cdn name %v existence", *profile.CDNName)
			log.Errorf("%v: %v", errString, err.Error())
			errs = append(errs, errors.New(errString))
		} else if !ok {
			errs = append(errs, fmt.Errorf("%v CDN does not exist", *profile.CDNName))
		}
	}

	// Validate profile does not already exist
	if profile.Name != nil {
		if ok, err := ProfileExistsByName(*profile.Name, tx); err != nil {
			errString := fmt.Sprintf("checking profile name %v existence", *profile.Name)
			log.Errorf("%v: %v", errString, err.Error())
			errs = append(errs, errors.New(errString))
		} else if ok {
			errs = append(errs, fmt.Errorf("a profile with the name \"%s\" already exists", *profile.Name))
		}
	}

	// Validate all parameters
	// export/import does not include secure flag
	// default value to not flag on validation
	secure := 1
	for i, pp := range profileImport.Parameters {
		if ppErrs := validateProfileParamPostFields(pp.ConfigFile, pp.Name, pp.Value, &secure); len(ppErrs) > 0 {
			for _, err := range ppErrs {
				errs = append(errs, errors.New("parameter "+strconv.Itoa(i)+": "+err.Error()))
			}
		}
	}

	if len(errs) > 0 {
		return util.JoinErrs(errs)
	}

	return nil
}

// ProfilesExistByIDs returns whether profiles exist for all the given ids, and any error.
// TODO move to helper package.
func ProfilesExistByIDs(ids []int64, tx *sql.Tx) (bool, error) {
	count := 0
	if err := tx.QueryRow(`SELECT count(*) from profile where id = ANY($1)`, pq.Array(ids)).Scan(&count); err != nil {
		return false, errors.New("querying profiles existence from id: " + err.Error())
	}
	return count == len(ids), nil
}

// ProfileExistsByID returns whether a profile with the given id exists, and any error.
// TODO move to helper package.
func ProfileExistsByID(id int64, tx *sql.Tx) (bool, error) {
	count := 0
	if err := tx.QueryRow(`SELECT count(*) from profile where id = $1`, id).Scan(&count); err != nil {
		return false, errors.New("querying profile existence from id: " + err.Error())
	}
	return count > 0, nil
}

// ProfileExistsByName returns whether a profile with the given name exists, and any error.
// TODO move to helper package.
func ProfileExistsByName(name string, tx *sql.Tx) (bool, error) {
	count := 0
	if err := tx.QueryRow(`SELECT count(*) from profile where name = $1`, name).Scan(&count); err != nil {
		return false, errors.New("querying profile existence from name: " + err.Error())
	}
	return count > 0, nil
}
