// Copyright 2020 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
// limitations under the License.

package database

import (
	"context"
	"fmt"
	"regexp"
	"strings"
	"time"
	"unicode"

	"github.com/googleapis/gax-go/v2"
	"google.golang.org/api/iterator"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
	databasepb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

var retryer = gax.OnCodes(
	[]codes.Code{codes.DeadlineExceeded, codes.Unavailable},
	gax.Backoff{Initial: time.Millisecond, Max: time.Millisecond, Multiplier: 1.0},
)

// CreateDatabaseWithRetry creates a new database and retries the call if the
// backend returns a retryable error. The actual CreateDatabase RPC is only
// retried if the initial call did not reach the server. In other cases, the
// client will query the backend for the long-running operation that was
// created by the initial RPC and return that operation.
func (c *DatabaseAdminClient) CreateDatabaseWithRetry(ctx context.Context, req *databasepb.CreateDatabaseRequest, opts ...gax.CallOption) (*CreateDatabaseOperation, error) {
	for {
		db, createErr := c.CreateDatabase(ctx, req, opts...)
		if createErr == nil {
			return db, nil
		}
		// Failed, check whether we should retry.
		delay, shouldRetry := retryer.Retry(createErr)
		if !shouldRetry {
			return nil, createErr
		}
		if err := gax.Sleep(ctx, delay); err != nil {
			return nil, err
		}
		// Extract the name of the database.
		dbName := extractDBName(req.CreateStatement)
		// Query the backend for any corresponding long-running operation to
		// determine whether we should retry the RPC or not.
		iter := c.ListDatabaseOperations(ctx, &databasepb.ListDatabaseOperationsRequest{
			Parent: req.Parent,
			Filter: fmt.Sprintf("(metadata.@type:type.googleapis.com/google.spanner.admin.database.v1.CreateDatabaseMetadata) AND (name:%s/databases/%s/operations/)", req.Parent, dbName),
		}, opts...)
		var mostRecentOp *longrunningpb.Operation
		for {
			op, err := iter.Next()
			if err == iterator.Done {
				break
			}
			if err != nil {
				return nil, err
			}
			// A running operation is the most recent and should be returned.
			if !op.Done {
				return c.CreateDatabaseOperation(op.Name), nil
			}
			if op.GetError() == nil {
				mostRecentOp = op
			}
		}
		if mostRecentOp == nil {
			continue
		}
		// Only finished operations found. Check whether the database exists.
		_, getErr := c.GetDatabase(ctx, &databasepb.GetDatabaseRequest{
			Name: fmt.Sprintf("%s/databases/%s", req.Parent, dbName),
		})
		if getErr == nil {
			// Database found, return one of the long-running operations that
			// has finished, which again should return the database.
			return c.CreateDatabaseOperation(mostRecentOp.Name), nil
		}
		if status.Code(getErr) == codes.NotFound {
			continue
		}
		// Error getting the database that was not NotFound.
		return nil, getErr
	}
}

var dbNameRegEx = regexp.MustCompile("\\s*CREATE\\s+DATABASE\\s+(.+)\\s*")

// extractDBName extracts the database name from a valid CREATE DATABASE <db>
// statement. We don't have to worry about invalid create statements, as those
// should already have been handled by the backend and should return a non-
// retryable error.
func extractDBName(createStatement string) string {
	if dbNameRegEx.MatchString(createStatement) {
		namePossiblyWithQuotes := strings.TrimRightFunc(dbNameRegEx.FindStringSubmatch(createStatement)[1], unicode.IsSpace)
		if len(namePossiblyWithQuotes) > 0 && namePossiblyWithQuotes[0] == '`' {
			if len(namePossiblyWithQuotes) > 5 && namePossiblyWithQuotes[1] == '`' && namePossiblyWithQuotes[2] == '`' {
				return string(namePossiblyWithQuotes[3 : len(namePossiblyWithQuotes)-3])
			}
			return string(namePossiblyWithQuotes[1 : len(namePossiblyWithQuotes)-1])
		}
		return string(namePossiblyWithQuotes)
	}
	return ""
}
