// Copyright 2021 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
//
//     https://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

package pubsublite

import (
	"context"
	"time"

	vkit "cloud.google.com/go/pubsublite/apiv1"
	pb "google.golang.org/genproto/googleapis/cloud/pubsublite/v1"
	tspb "google.golang.org/protobuf/types/known/timestamppb"
)

// SeekTarget is the target location to seek a subscription to. Implemented by
// BacklogLocation, PublishTime, EventTime.
type SeekTarget interface {
	setRequest(req *pb.SeekSubscriptionRequest)
}

// BacklogLocation refers to a location with respect to the message backlog.
// It implements the SeekTarget interface.
type BacklogLocation int

const (
	// End refers to the location past all currently published messages. End
	// skips the entire message backlog.
	End BacklogLocation = iota + 1

	// Beginning refers to the location of the oldest retained message.
	Beginning
)

func (b BacklogLocation) setRequest(req *pb.SeekSubscriptionRequest) {
	target := pb.SeekSubscriptionRequest_TAIL
	if b == End {
		target = pb.SeekSubscriptionRequest_HEAD
	}
	req.Target = &pb.SeekSubscriptionRequest_NamedTarget_{
		NamedTarget: target,
	}
}

// PublishTime is a message publish timestamp. It implements the SeekTarget
// interface.
type PublishTime time.Time

func (p PublishTime) setRequest(req *pb.SeekSubscriptionRequest) {
	req.Target = &pb.SeekSubscriptionRequest_TimeTarget{
		TimeTarget: &pb.TimeTarget{
			Time: &pb.TimeTarget_PublishTime{tspb.New(time.Time(p))},
		},
	}
}

// EventTime is a message event timestamp. It implements the SeekTarget
// interface.
type EventTime time.Time

func (e EventTime) setRequest(req *pb.SeekSubscriptionRequest) {
	req.Target = &pb.SeekSubscriptionRequest_TimeTarget{
		TimeTarget: &pb.TimeTarget{
			Time: &pb.TimeTarget_EventTime{tspb.New(time.Time(e))},
		},
	}
}

// SeekSubscriptionOption is reserved for future options.
type SeekSubscriptionOption interface{}

// SeekSubscriptionResult is the result of a seek subscription operation.
// Currently empty.
type SeekSubscriptionResult struct{}

// OperationMetadata stores metadata for long-running operations.
type OperationMetadata struct {
	// The target of the operation. For example, targets of seeks are
	// subscriptions, structured like:
	// "projects/PROJECT_ID/locations/LOCATION/subscriptions/SUBSCRIPTION_ID"
	Target string

	// The verb describing the kind of operation.
	Verb string

	// The time the operation was created.
	CreateTime time.Time

	// The time the operation finished running. Is zero if the operation has not
	// completed.
	EndTime time.Time
}

func protoToOperationMetadata(o *pb.OperationMetadata) (*OperationMetadata, error) {
	if err := o.GetCreateTime().CheckValid(); err != nil {
		return nil, err
	}
	metadata := &OperationMetadata{
		Target:     o.Target,
		Verb:       o.Verb,
		CreateTime: o.GetCreateTime().AsTime(),
	}
	if o.GetEndTime() != nil {
		if err := o.GetEndTime().CheckValid(); err != nil {
			return nil, err
		}
		metadata.EndTime = o.GetEndTime().AsTime()
	}
	return metadata, nil
}

// SeekSubscriptionOperation manages a long-running seek operation from
// AdminClient.SeekSubscription.
type SeekSubscriptionOperation struct {
	op *vkit.SeekSubscriptionOperation
}

// Name returns the path of the seek operation, in the format:
// "projects/PROJECT_ID/locations/LOCATION/operations/OPERATION_ID".
func (s *SeekSubscriptionOperation) Name() string {
	return s.op.Name()
}

// Done returns whether the seek operation has completed.
func (s *SeekSubscriptionOperation) Done() bool {
	return s.op.Done()
}

// Metadata returns metadata associated with the seek operation. To get the
// latest metadata, call this method after a successful call to Wait.
func (s *SeekSubscriptionOperation) Metadata() (*OperationMetadata, error) {
	m, err := s.op.Metadata()
	if err != nil {
		return nil, err
	}
	return protoToOperationMetadata(m)
}

// Wait polls until the seek operation is complete and returns one of the
// following:
//  - A SeekSubscriptionResult and nil error if the operation is complete and
//    succeeded.
//  - Error containing failure reason if the operation is complete and failed.
//  - Error if polling the operation status failed due to a non-retryable error.
func (s *SeekSubscriptionOperation) Wait(ctx context.Context) (*SeekSubscriptionResult, error) {
	if _, err := s.op.Wait(ctx); err != nil {
		return nil, err
	}
	return &SeekSubscriptionResult{}, nil
}
