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 "errors"
import "fmt"
import "regexp"
import "database/sql"
import "math"
import "strconv"
import "strings"
import "time"

import "github.com/apache/trafficcontrol/lib/go-log"

import "github.com/go-ozzo/ozzo-validation"
import "github.com/go-ozzo/ozzo-validation/is"

// MaxTTL is the maximum value of TTL representable as a time.Duration object, which is used
// internally by InvalidationJobInput objects to store the TTL.
const MaxTTL = math.MaxInt64 / 3600000000000

var twoDays = time.Hour * 48

// ValidJobRegexPrefix matches the only valid prefixes for a relative-path Content Invalidation Job regex
var ValidJobRegexPrefix = regexp.MustCompile(`^\?/.*$`)

// InvalidationJob represents a content invalidation job as returned by the API.
type InvalidationJob struct {
	AssetURL        *string `json:"assetUrl"`
	CreatedBy       *string `json:"createdBy"`
	DeliveryService *string `json:"deliveryService"`
	ID              *uint64 `json:"id"`
	Keyword         *string `json:"keyword"`
	Parameters      *string `json:"parameters"`

	// StartTime is the time at which the job will come into effect. Must be in the future, but will
	// fail to Validate if it is further in the future than two days.
	StartTime *Time `json:"startTime"`
}

// InvalidationJobInput represents user input intending to create or modify a content invalidation job.
type InvalidationJobInput struct {

	// DeliveryService needs to be an identifier for a Delivery Service. It can be either a string - in which
	// case it is treated as an XML_ID - or a float64 (because that's the type used by encoding/json
	// to represent all JSON numbers) - in which case it's treated as an integral, unique identifier
	// (and any fractional part is discarded, i.e. 2.34 -> 2)
	DeliveryService *interface{} `json:"deliveryService"`

	// Regex is a regular expression which not only must be valid, but should also start with '/'
	// (or escaped: '\/')
	Regex *string `json:"regex"`

	// StartTime is the time at which the job will come into effect. Must be in the future.
	StartTime *Time `json:"startTime"`

	// TTL indicates the Time-to-Live of the job. This can be either a valid string for
	// time.ParseDuration, or a float64 indicating the number of hours. Note that regardless of the
	// actual value here, Traffic Ops will only consider it rounded down to the nearest natural
	// number
	TTL *interface{} `json:"ttl"`

	dsid *uint          `json:"-"`
	ttl  *time.Duration `json:"-"`
}

// UserInvalidationJobInput Represents legacy-style user input to the /user/current/jobs API endpoint.
// This is much less flexible than InvalidationJobInput, which should be used instead when possible.
type UserInvalidationJobInput struct {
	DSID  *uint   `json:"dsId"`
	Regex *string `json:"regex"`

	// StartTime is the time at which the job will come into effect. Must be in the future, but will
	// fail to Validate if it is further in the future than two days.
	StartTime *Time   `json:"startTime"`
	TTL       *uint64 `json:"ttl"`
	Urgent    *bool   `json:"urgent"`
}

// UserInvalidationJob is a full representation of content invalidation jobs as stored in the
// database, including several unused fields.
type UserInvalidationJob struct {

	// Agent is unused, and developers should never count on it containing or meaning anything.
	Agent    *uint   `json:"agent"`
	AssetURL *string `json:"assetUrl"`

	// AssetType is unused, and developers should never count on it containing or meaning anything.
	AssetType       *string `json:"assetType"`
	DeliveryService *string `json:"deliveryService"`
	EnteredTime     *Time   `json:"enteredTime"`
	ID              *uint   `json:"id"`
	Keyword         *string `json:"keyword"`

	// ObjectName is unused, and developers should never count on it containing or meaning anything.
	ObjectName *string `json:"objectName"`

	// ObjectType is unused, and developers should never count on it containing or meaning anything.
	ObjectType *string `json:"objectType"`
	Parameters *string `json:"parameters"`
	Username   *string `json:"username"`
}

// TTLHours gets the number of hours of the job's TTL - rounded down to the nearest natural number,
// or an error if it is an invalid value.
func (j *InvalidationJobInput) TTLHours() (uint, error) {
	if j.ttl != nil {
		return uint((*j.ttl).Hours()), nil
	}
	if j.TTL == nil {
		return 0, errors.New("Attempted to convert a nil TTL into hours")
	}

	var ret uint
	switch t := (*j.TTL).(type) {
	case float64:
		v := (*j.TTL).(float64)
		if v < 0 {
			return 0, errors.New("TTL cannot be negative!")
		}
		if v >= MaxTTL {
			return 0, fmt.Errorf("TTL cannot exceed %d hours!", MaxTTL)
		}
		ttl := time.Duration(int64(v * 3600000000000))
		j.ttl = &ttl
		ret = uint(ttl.Hours())

	case string:
		d, err := time.ParseDuration((*j.TTL).(string))
		if err != nil || d.Hours() < 1 {
			return 0, fmt.Errorf("Invalid duration entered for TTL! Must be at least one hour, but no more than %d hours!", MaxTTL)
		}
		j.ttl = &d
		ret = uint(d.Hours())

	default:
		log.Errorf("unsupported TTL key type: %T\n", t)
		return 0, errors.New("Unknown error occurred")
	}

	return ret, nil
}

// DSID gets the integral, unique identifier of the Delivery Service identified by
// InvalidationJobInput.DeliveryService
//
// This requires a transaction connected to a Traffic Ops database, because if DeliveryService is
// an xml_id, a database lookup will be necessary to get the unique, integral identifier. Thus,
// this method also checks for the existence of the identified Delivery Service, and will return
// an error if it does not exist.
func (j *InvalidationJobInput) DSID(tx *sql.Tx) (uint, error) {
	if j.dsid != nil {
		return *j.dsid, nil
	}

	if j.DeliveryService == nil {
		return 0, errors.New("Attempted to turn a nil DeliveryService into a DSID")
	}
	if tx == nil {
		return 0, errors.New("Attempted to turn a DeliveryService into a DSID with no DB connection")
	}

	var ret uint
	switch t := (*j.DeliveryService).(type) {
	case float64:
		v := (*j.DeliveryService).(float64)
		if v < 0 {
			return 0, errors.New("Delivery Service ID cannot be negative")
		}

		u := uint(v)
		var exists bool
		row := tx.QueryRow(`SELECT EXISTS(SELECT * FROM deliveryservice WHERE id=$1)`, u)
		if err := row.Scan(&exists); err != nil {
			log.Errorf("Error checking for deliveryservice existence in DSID: %v\n", err)
			return 0, errors.New("Unknown error occurred")
		} else if !exists {
			return 0, fmt.Errorf("No Delivery Service exists matching identifier: %v", *j.DeliveryService)
		}

		j.dsid = &u
		return u, nil

	case string:
		row := tx.QueryRow(`SELECT id FROM deliveryservice WHERE xml_id=$1`, *j.DeliveryService)
		if err := row.Scan(&ret); err != nil {
			if err == sql.ErrNoRows {
				return 0, fmt.Errorf("No DeliveryService exists matching identifier: %v", *j.DeliveryService)
			}
			return 0, errors.New("Unknown error occurred")
		}
		j.dsid = &ret
		return ret, nil

	default:
		log.Errorf("unsupported DS key type: %T\n", t)
		return 0, errors.New("Unknown error occurred")

	}
}

// Validate validates that the user input is correct, given a transaction
// connected to the Traffic Ops database. In particular, it enforces the
// constraints described on each field, as well as ensuring they actually exist.
// This method calls InvalidationJobInput.DSID to validate the DeliveryService
// field.
//
// This returns an error describing any and all problematic fields encountered during validation.
func (job *InvalidationJobInput) Validate(tx *sql.Tx) error {
	errs := []string{}
	err := validation.ValidateStruct(job,
		validation.Field(&job.DeliveryService, validation.Required),
		validation.Field(&job.Regex, validation.Required, validation.NewStringRule(func(s string) bool {
			return strings.HasPrefix(s, `\/`) || strings.HasPrefix(s, "/")
		}, `must start with '/' (or '\/')`)),
		validation.Field(&job.TTL, validation.Required),
	)

	if err != nil {
		errs = append(errs, err.Error())
	}

	if job.DeliveryService != nil {
		if _, err := job.DSID(tx); err != nil {
			errs = append(errs, err.Error())
		}
	}

	if job.Regex != nil && *job.Regex != "" {
		if _, err := regexp.Compile(*job.Regex); err != nil {
			errs = append(errs, "regex: is not a valid Regular Expression: "+err.Error())
		}
	}

	if job.StartTime == nil {
		errs = append(errs, "startTime: cannot be blank")
	} else if job.StartTime.Time.Before(time.Now()) {
		errs = append(errs, "startTime: must be in the future")
	}

	if job.TTL != nil {
		hours, err := job.TTLHours()
		if err != nil {
			errs = append(errs, "ttl: must be a number of hours, or a duration string e.g. '48h'")
		}
		var maxDays uint
		err = tx.QueryRow(`SELECT value FROM parameter WHERE name='maxRevalDurationDays' AND config_file='regex_revalidate.config'`).Scan(&maxDays)
		maxHours := maxDays * 24
		if err == nil && hours > maxHours { // silently ignore other errors too
			errs = append(errs, "ttl: cannot exceed "+strconv.FormatUint(uint64(maxHours), 10)+"!")
		}
	}

	if len(errs) > 0 {
		return errors.New(strings.Join(errs, ", "))
	}
	return nil
}

// Validate checks that the InvalidationJob is valid, by ensuring all of its fields are well-defined.
//
// This returns an error describing any and all problematic fields encountered during validation.
func (job *InvalidationJob) Validate() error {
	errs := []string{}
	err := validation.ValidateStruct(job,
		validation.Field(&job.AssetURL, validation.Required, is.URL),
		validation.Field(&job.CreatedBy, validation.Required),
		validation.Field(&job.DeliveryService, validation.Required),
		validation.Field(&job.ID, validation.Required),
		validation.Field(&job.Keyword, validation.Required),
		validation.Field(&job.Parameters, validation.Required),
	)

	if err != nil {
		errs = append(errs, err.Error())
	}

	if job.StartTime == nil {
		return errors.New(strings.Join(append(errs, "startTime: cannot be blank"), ", "))
	}

	if job.StartTime.After(time.Now().Add(twoDays)) {
		errs = append(errs, "startTime: must be within two days from now")
	}

	if job.StartTime.Before(time.Now()) {
		errs = append(errs, "startTime: cannot be in the past")
	}

	if len(errs) > 0 {
		return errors.New(strings.Join(errs, ", "))
	}

	return nil
}

// Validate validates that the user input is correct, given a transaction
// connected to the Traffic Ops database.
//
// This requires a database transaction to check that the DSID is a valid
// identifier for an existing Delivery Service.
//
// Returns an error describing any and all problematic fields encountered during
// validation.
func (job *UserInvalidationJobInput) Validate(tx *sql.Tx) error {
	errs := []string{}
	err := validation.ValidateStruct(job,
		validation.Field(&job.Regex, validation.Required, validation.NewStringRule(func(s string) bool {
			return strings.HasPrefix(s, `\/`) || strings.HasPrefix(s, "/")
		}, `must start with '/' (or '\/')`)),
		validation.Field(&job.DSID, validation.Required),
		validation.Field(&job.TTL, validation.Required),
	)
	if err != nil {
		errs = append(errs, err.Error())
	}

	if job.StartTime == nil {
		errs = append(errs, "startTime: cannot be blank")
	} else if job.StartTime.After(time.Now().Add(twoDays)) {
		errs = append(errs, "startTime: must be within two days")
	}

	if job.Regex != nil && *(job.Regex) != "" {
		if _, err := regexp.Compile(*(job.Regex)); err != nil {
			errs = append(errs, "regex: is not a valid regular expression: "+err.Error())
		}
	}

	if job.DSID != nil {
		row := tx.QueryRow(`SELECT id FROM deliveryservice WHERE id = $1::bigint`, job.DSID)
		var id uint
		if err := row.Scan(&id); err != nil {
			log.Errorln(err.Error())
			errs = append(errs, "no Delivery Service corresponding to 'dsId'")
		}
	}

	if job.TTL != nil {
		row := tx.QueryRow(`SELECT value FROM parameter WHERE name='maxRevalDurationDays' AND config_file='regex_revalidate.config'`)
		var maxDays uint64
		err := row.Scan(&maxDays)
		maxHours := maxDays * 24
		if err == sql.ErrNoRows && MaxTTL < *(job.TTL) {
			errs = append(errs, "ttl: cannot exceed "+strconv.FormatUint(MaxTTL, 10))
		} else if err == nil && maxHours < *(job.TTL) { // silently ignore other errors
			errs = append(errs, "ttl: cannot exceed "+strconv.FormatUint(maxHours, 10))
		} else if *(job.TTL) < 1 {
			errs = append(errs, "ttl: must be at least 1")
		}
	}

	if len(errs) > 0 {
		return errors.New(strings.Join(errs, ", "))
	}
	return nil
}
