// Copyright 2018 The LUCI Authors.
//
// 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 model

import (
	"crypto/sha256"
	"encoding/json"
	"fmt"
	"sort"
	"time"

	"go.chromium.org/luci/common/data/strpair"
	"go.chromium.org/luci/milo/common/model/milostatus"
)

// PoolDescriptor describes the attributes of a pool in "tag:value" format.
// This is defined as Swarming Dimensions + Hostname.
type PoolDescriptor []string

// SwarmingHostnameKey is a magic PoolDescriptor tag containing the Swarming Hostname.
const SwarmingHostnameKey = "swarming_hostname"

// NewPoolDescriptor creates a new PoolDescriptor given a swarming hostname
// and a slice of dimensions.  The dimensions are expected to be in "key:value" format,
// where the key is the tag name.  This is the same format returned by the Swarming API.
func NewPoolDescriptor(host string, dimensions []string) PoolDescriptor {
	desc := make([]string, 0, len(dimensions)+1)
	desc = append(desc, fmt.Sprintf("%s:%s", SwarmingHostnameKey, host))
	desc = append(desc, dimensions...)
	sort.Strings(desc)
	return desc
}

// PoolID returns they ID for a BotPool with the specified PoolDescriptor.
// The ID is a SHA256 hash in hex form.
// descriptor must be pre-sorted (I.E. Created with NewPoolDescriptor).
func (d PoolDescriptor) PoolID() string {
	s, err := json.Marshal(d)
	if err != nil {
		// This should never happen for a slice of strings.
		panic(err)
	}
	return fmt.Sprintf("%x", sha256.Sum256(s))
}

// Host returns the swarming_hostname item of the PoolDescriptor.
func (d PoolDescriptor) Host() string {
	return strpair.ParseMap(d).Get(SwarmingHostnameKey)
}

// Dimensions returns a copy of the PoolDescriptor without the swarming_hostname item
// in strpair.Map format.
func (d PoolDescriptor) Dimensions() strpair.Map {
	m := strpair.ParseMap(d)
	m.Del(SwarmingHostnameKey)
	return m
}

// BotPoolKind is the name of the datastore entity kind of BotPool.
const BotPoolKind = "BotPool"

// BotPool is the execution pool information associated with a
// set of Swarming bots.  This information is periodically refreshed from Swarming.
type BotPool struct {
	// PoolID is an identifier for the BotPool.
	// PoolID must match the Descriptor.
	// This field should always be constructed with PoolID().
	PoolID string `gae:"$id"`

	// Descriptor uniquely describes this BotPool.
	// It is defined as Swarming Dimensions + Hostname.
	Descriptor PoolDescriptor

	// Bots is a slice of bots in the pool, along with their statuses.
	Bots []Bot `gae:",noindex"`

	// LastUpdate is when this entity was last updated.
	LastUpdate time.Time
}

// Bot represents a single job executor.
type Bot struct {
	// Name is an identifier for the Bot.  This is usually a short hostname.
	Name string
	// URL is a link to a bot page, if available.
	URL string
	// Status is the current status of the Bot.
	Status milostatus.BotStatus
	// LastSeen denotes when the Bot was last seen.
	LastSeen time.Time
}
