/*
Copyright 2015 Google LLC

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 bigtable

import (
	"fmt"
	"strings"
	"time"

	durpb "github.com/golang/protobuf/ptypes/duration"
	bttdpb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
)

// A GCPolicy represents a rule that determines which cells are eligible for garbage collection.
type GCPolicy interface {
	String() string
	proto() *bttdpb.GcRule
}

// IntersectionPolicy returns a GC policy that only applies when all its sub-policies apply.
func IntersectionPolicy(sub ...GCPolicy) GCPolicy { return intersectionPolicy{sub} }

type intersectionPolicy struct {
	sub []GCPolicy
}

func (ip intersectionPolicy) String() string {
	var ss []string
	for _, sp := range ip.sub {
		ss = append(ss, sp.String())
	}
	return "(" + strings.Join(ss, " && ") + ")"
}

func (ip intersectionPolicy) proto() *bttdpb.GcRule {
	inter := &bttdpb.GcRule_Intersection{}
	for _, sp := range ip.sub {
		inter.Rules = append(inter.Rules, sp.proto())
	}
	return &bttdpb.GcRule{
		Rule: &bttdpb.GcRule_Intersection_{Intersection: inter},
	}
}

// UnionPolicy returns a GC policy that applies when any of its sub-policies apply.
func UnionPolicy(sub ...GCPolicy) GCPolicy { return unionPolicy{sub} }

type unionPolicy struct {
	sub []GCPolicy
}

func (up unionPolicy) String() string {
	var ss []string
	for _, sp := range up.sub {
		ss = append(ss, sp.String())
	}
	return "(" + strings.Join(ss, " || ") + ")"
}

func (up unionPolicy) proto() *bttdpb.GcRule {
	union := &bttdpb.GcRule_Union{}
	for _, sp := range up.sub {
		union.Rules = append(union.Rules, sp.proto())
	}
	return &bttdpb.GcRule{
		Rule: &bttdpb.GcRule_Union_{Union: union},
	}
}

// MaxVersionsPolicy returns a GC policy that applies to all versions of a cell
// except for the most recent n.
func MaxVersionsPolicy(n int) GCPolicy { return maxVersionsPolicy(n) }

type maxVersionsPolicy int

func (mvp maxVersionsPolicy) String() string { return fmt.Sprintf("versions() > %d", int(mvp)) }

func (mvp maxVersionsPolicy) proto() *bttdpb.GcRule {
	return &bttdpb.GcRule{Rule: &bttdpb.GcRule_MaxNumVersions{MaxNumVersions: int32(mvp)}}
}

// MaxAgePolicy returns a GC policy that applies to all cells
// older than the given age.
func MaxAgePolicy(d time.Duration) GCPolicy { return maxAgePolicy(d) }

type maxAgePolicy time.Duration

var units = []struct {
	d      time.Duration
	suffix string
}{
	{24 * time.Hour, "d"},
	{time.Hour, "h"},
	{time.Minute, "m"},
}

func (ma maxAgePolicy) String() string {
	d := time.Duration(ma)
	for _, u := range units {
		if d%u.d == 0 {
			return fmt.Sprintf("age() > %d%s", d/u.d, u.suffix)
		}
	}
	return fmt.Sprintf("age() > %d", d/time.Microsecond)
}

func (ma maxAgePolicy) proto() *bttdpb.GcRule {
	// This doesn't handle overflows, etc.
	// Fix this if people care about GC policies over 290 years.
	ns := time.Duration(ma).Nanoseconds()
	return &bttdpb.GcRule{
		Rule: &bttdpb.GcRule_MaxAge{MaxAge: &durpb.Duration{
			Seconds: ns / 1e9,
			Nanos:   int32(ns % 1e9),
		}},
	}
}

// GCRuleToString converts the given GcRule proto to a user-visible string.
func GCRuleToString(rule *bttdpb.GcRule) string {
	if rule == nil {
		return "<default>"
	}
	switch r := rule.Rule.(type) {
	case *bttdpb.GcRule_MaxNumVersions:
		return MaxVersionsPolicy(int(r.MaxNumVersions)).String()
	case *bttdpb.GcRule_MaxAge:
		return MaxAgePolicy(time.Duration(r.MaxAge.Seconds) * time.Second).String()
	case *bttdpb.GcRule_Intersection_:
		return joinRules(r.Intersection.Rules, " && ")
	case *bttdpb.GcRule_Union_:
		return joinRules(r.Union.Rules, " || ")
	default:
		return ""
	}
}

func joinRules(rules []*bttdpb.GcRule, sep string) string {
	var chunks []string
	for _, r := range rules {
		chunks = append(chunks, GCRuleToString(r))
	}
	return "(" + strings.Join(chunks, sep) + ")"
}
