// Copyright 2017 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 pubsub

import (
	"context"
	"fmt"
	"strings"
	"time"

	pb "cloud.google.com/go/pubsub/apiv1/pubsubpb"
	fmpb "google.golang.org/protobuf/types/known/fieldmaskpb"
	"google.golang.org/protobuf/types/known/timestamppb"
)

// Snapshot is a reference to a PubSub snapshot.
type Snapshot struct {
	c *Client

	// The fully qualified identifier for the snapshot, in the format "projects/<projid>/snapshots/<snap>"
	name string
}

// ID returns the unique identifier of the snapshot within its project.
func (s *Snapshot) ID() string {
	slash := strings.LastIndex(s.name, "/")
	if slash == -1 {
		// name is not a fully-qualified name.
		panic("bad snapshot name")
	}
	return s.name[slash+1:]
}

// SetLabels sets or replaces the labels on a given snapshot.
func (s *Snapshot) SetLabels(ctx context.Context, label map[string]string) (*SnapshotConfig, error) {
	sc, err := s.c.subc.UpdateSnapshot(ctx, &pb.UpdateSnapshotRequest{
		Snapshot: &pb.Snapshot{
			Name:   s.name,
			Labels: label,
		},
		UpdateMask: &fmpb.FieldMask{
			Paths: []string{"labels"},
		},
	})
	if err != nil {
		return nil, err
	}
	return toSnapshotConfig(sc, s.c)
}

// SnapshotConfig contains the details of a Snapshot.
type SnapshotConfig struct {
	*Snapshot
	Topic      *Topic
	Expiration time.Time
	// The set of labels for the snapshot.
	Labels map[string]string
}

// Snapshot creates a reference to a snapshot.
func (c *Client) Snapshot(id string) *Snapshot {
	return &Snapshot{
		c:    c,
		name: fmt.Sprintf("projects/%s/snapshots/%s", c.projectID, id),
	}
}

// Snapshots returns an iterator which returns snapshots for this project.
func (c *Client) Snapshots(ctx context.Context) *SnapshotConfigIterator {
	it := c.subc.ListSnapshots(ctx, &pb.ListSnapshotsRequest{
		Project: c.fullyQualifiedProjectName(),
	})
	next := func() (*SnapshotConfig, error) {
		snap, err := it.Next()
		if err != nil {
			return nil, err
		}
		return toSnapshotConfig(snap, c)
	}
	return &SnapshotConfigIterator{next: next}
}

// SnapshotConfigIterator is an iterator that returns a series of snapshots.
type SnapshotConfigIterator struct {
	next func() (*SnapshotConfig, error)
}

// Next returns the next SnapshotConfig. Its second return value is iterator.Done if there are no more results.
// Once Next returns iterator.Done, all subsequent calls will return iterator.Done.
func (snaps *SnapshotConfigIterator) Next() (*SnapshotConfig, error) {
	return snaps.next()
}

// Delete deletes a snapshot.
func (s *Snapshot) Delete(ctx context.Context) error {
	return s.c.subc.DeleteSnapshot(ctx, &pb.DeleteSnapshotRequest{Snapshot: s.name})
}

// SeekToTime seeks the subscription to a point in time.
//
// Messages retained in the subscription that were published before this
// time are marked as acknowledged, and messages retained in the
// subscription that were published after this time are marked as
// unacknowledged. Note that this operation affects only those messages
// retained in the subscription (configured by SnapshotConfig). For example,
// if `time` corresponds to a point before the message retention
// window (or to a point before the system's notion of the subscription
// creation time), only retained messages will be marked as unacknowledged,
// and already-expunged messages will not be restored.
func (s *Subscription) SeekToTime(ctx context.Context, t time.Time) error {
	ts := timestamppb.New(t)
	_, err := s.c.subc.Seek(ctx, &pb.SeekRequest{
		Subscription: s.name,
		Target:       &pb.SeekRequest_Time{Time: ts},
	})
	return err
}

// CreateSnapshot creates a new snapshot from this subscription.
// The snapshot will be for the topic this subscription is subscribed to.
// If the name is empty string, a unique name is assigned.
//
// The created snapshot is guaranteed to retain:
//
//	(a) The existing backlog on the subscription. More precisely, this is
//	    defined as the messages in the subscription's backlog that are
//	    unacknowledged when Snapshot returns without error.
//	(b) Any messages published to the subscription's topic following
//	    Snapshot returning without error.
func (s *Subscription) CreateSnapshot(ctx context.Context, name string) (*SnapshotConfig, error) {
	if name != "" {
		name = fmt.Sprintf("projects/%s/snapshots/%s", strings.Split(s.name, "/")[1], name)
	}
	snap, err := s.c.subc.CreateSnapshot(ctx, &pb.CreateSnapshotRequest{
		Name:         name,
		Subscription: s.name,
	})
	if err != nil {
		return nil, err
	}
	return toSnapshotConfig(snap, s.c)
}

// SeekToSnapshot seeks the subscription to a snapshot.
//
// The snapshot need not be created from this subscription,
// but it must be for the topic this subscription is subscribed to.
func (s *Subscription) SeekToSnapshot(ctx context.Context, snap *Snapshot) error {
	_, err := s.c.subc.Seek(ctx, &pb.SeekRequest{
		Subscription: s.name,
		Target:       &pb.SeekRequest_Snapshot{Snapshot: snap.name},
	})
	return err
}

func toSnapshotConfig(snap *pb.Snapshot, c *Client) (*SnapshotConfig, error) {
	exp := snap.ExpireTime.AsTime()
	return &SnapshotConfig{
		Snapshot:   &Snapshot{c: c, name: snap.Name},
		Topic:      newTopic(c, snap.Topic),
		Expiration: exp,
		Labels:     snap.Labels,
	}, nil
}
