/*
Copyright 2018 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 cloud

import (
	"context"
	"fmt"

	"k8s.io/klog"

	alpha "google.golang.org/api/compute/v0.alpha"
	beta "google.golang.org/api/compute/v0.beta"
	ga "google.golang.org/api/compute/v1"
	"google.golang.org/api/googleapi"

	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
)

const (
	operationStatusDone = "DONE"
)

// operation is a GCE operation that can be watied on.
type operation interface {
	// isDone queries GCE for the done status. This call can block.
	isDone(ctx context.Context) (bool, error)
	// error returns the resulting error of the operation. This may be nil if the operations
	// was successful.
	error() error
	// rateLimitKey returns the rate limit key to use for the given operation.
	// This rate limit will govern how fast the server will be polled for
	// operation completion status.
	rateLimitKey() *RateLimitKey
}

type gaOperation struct {
	s         *Service
	projectID string
	key       *meta.Key
	err       error
}

func (o *gaOperation) String() string {
	return fmt.Sprintf("gaOperation{%q, %v}", o.projectID, o.key)
}

func (o *gaOperation) isDone(ctx context.Context) (bool, error) {
	var (
		op  *ga.Operation
		err error
	)

	switch o.key.Type() {
	case meta.Regional:
		op, err = o.s.GA.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("GA.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
	case meta.Zonal:
		op, err = o.s.GA.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("GA.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
	case meta.Global:
		op, err = o.s.GA.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("GA.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
	default:
		return false, fmt.Errorf("invalid key type: %#v", o.key)
	}
	if err != nil {
		return false, err
	}
	if op == nil || op.Status != operationStatusDone {
		return false, nil
	}

	if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
		e := op.Error.Errors[0]
		o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
	}
	return true, nil
}

func (o *gaOperation) rateLimitKey() *RateLimitKey {
	return &RateLimitKey{
		ProjectID: o.projectID,
		Operation: "Get",
		Service:   "Operations",
		Version:   meta.VersionGA,
	}
}

func (o *gaOperation) error() error {
	return o.err
}

type alphaOperation struct {
	s         *Service
	projectID string
	key       *meta.Key
	err       error
}

func (o *alphaOperation) String() string {
	return fmt.Sprintf("alphaOperation{%q, %v}", o.projectID, o.key)
}

func (o *alphaOperation) isDone(ctx context.Context) (bool, error) {
	var (
		op  *alpha.Operation
		err error
	)

	switch o.key.Type() {
	case meta.Regional:
		op, err = o.s.Alpha.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Alpha.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
	case meta.Zonal:
		op, err = o.s.Alpha.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Alpha.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
	case meta.Global:
		op, err = o.s.Alpha.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Alpha.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
	default:
		return false, fmt.Errorf("invalid key type: %#v", o.key)
	}
	if err != nil {
		return false, err
	}
	if op == nil || op.Status != operationStatusDone {
		return false, nil
	}

	if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
		e := op.Error.Errors[0]
		o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
	}
	return true, nil
}

func (o *alphaOperation) rateLimitKey() *RateLimitKey {
	return &RateLimitKey{
		ProjectID: o.projectID,
		Operation: "Get",
		Service:   "Operations",
		Version:   meta.VersionAlpha,
	}
}

func (o *alphaOperation) error() error {
	return o.err
}

type betaOperation struct {
	s         *Service
	projectID string
	key       *meta.Key
	err       error
}

func (o *betaOperation) String() string {
	return fmt.Sprintf("betaOperation{%q, %v}", o.projectID, o.key)
}

func (o *betaOperation) isDone(ctx context.Context) (bool, error) {
	var (
		op  *beta.Operation
		err error
	)

	switch o.key.Type() {
	case meta.Regional:
		op, err = o.s.Beta.RegionOperations.Get(o.projectID, o.key.Region, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Beta.RegionOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Region, o.key.Name, op, err, ctx)
	case meta.Zonal:
		op, err = o.s.Beta.ZoneOperations.Get(o.projectID, o.key.Zone, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Beta.ZoneOperations.Get(%v, %v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Zone, o.key.Name, op, err, ctx)
	case meta.Global:
		op, err = o.s.Beta.GlobalOperations.Get(o.projectID, o.key.Name).Context(ctx).Do()
		klog.V(5).Infof("Beta.GlobalOperations.Get(%v, %v) = %+v, %v; ctx = %v", o.projectID, o.key.Name, op, err, ctx)
	default:
		return false, fmt.Errorf("invalid key type: %#v", o.key)
	}
	if err != nil {
		return false, err
	}
	if op == nil || op.Status != operationStatusDone {
		return false, nil
	}

	if op.Error != nil && len(op.Error.Errors) > 0 && op.Error.Errors[0] != nil {
		e := op.Error.Errors[0]
		o.err = &googleapi.Error{Code: int(op.HttpErrorStatusCode), Message: fmt.Sprintf("%v - %v", e.Code, e.Message)}
	}
	return true, nil
}

func (o *betaOperation) rateLimitKey() *RateLimitKey {
	return &RateLimitKey{
		ProjectID: o.projectID,
		Operation: "Get",
		Service:   "Operations",
		Version:   meta.VersionBeta,
	}
}

func (o *betaOperation) error() error {
	return o.err
}
