// 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 storage

import (
	"cloud.google.com/go/iam"
	"cloud.google.com/go/internal/trace"
	"golang.org/x/net/context"
	raw "google.golang.org/api/storage/v1"
	iampb "google.golang.org/genproto/googleapis/iam/v1"
)

// IAM provides access to IAM access control for the bucket.
func (b *BucketHandle) IAM() *iam.Handle {
	return iam.InternalNewHandleClient(&iamClient{
		raw:         b.c.raw,
		userProject: b.userProject,
	}, b.name)
}

// iamClient implements the iam.client interface.
type iamClient struct {
	raw         *raw.Service
	userProject string
}

func (c *iamClient) Get(ctx context.Context, resource string) (p *iampb.Policy, err error) {
	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Get")
	defer func() { trace.EndSpan(ctx, err) }()

	call := c.raw.Buckets.GetIamPolicy(resource)
	setClientHeader(call.Header())
	if c.userProject != "" {
		call.UserProject(c.userProject)
	}
	var rp *raw.Policy
	err = runWithRetry(ctx, func() error {
		rp, err = call.Context(ctx).Do()
		return err
	})
	if err != nil {
		return nil, err
	}
	return iamFromStoragePolicy(rp), nil
}

func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) (err error) {
	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Set")
	defer func() { trace.EndSpan(ctx, err) }()

	rp := iamToStoragePolicy(p)
	call := c.raw.Buckets.SetIamPolicy(resource, rp)
	setClientHeader(call.Header())
	if c.userProject != "" {
		call.UserProject(c.userProject)
	}
	return runWithRetry(ctx, func() error {
		_, err := call.Context(ctx).Do()
		return err
	})
}

func (c *iamClient) Test(ctx context.Context, resource string, perms []string) (permissions []string, err error) {
	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.IAM.Test")
	defer func() { trace.EndSpan(ctx, err) }()

	call := c.raw.Buckets.TestIamPermissions(resource, perms)
	setClientHeader(call.Header())
	if c.userProject != "" {
		call.UserProject(c.userProject)
	}
	var res *raw.TestIamPermissionsResponse
	err = runWithRetry(ctx, func() error {
		res, err = call.Context(ctx).Do()
		return err
	})
	if err != nil {
		return nil, err
	}
	return res.Permissions, nil
}

func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy {
	return &raw.Policy{
		Bindings: iamToStorageBindings(ip.Bindings),
		Etag:     string(ip.Etag),
	}
}

func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings {
	var rbs []*raw.PolicyBindings
	for _, ib := range ibs {
		rbs = append(rbs, &raw.PolicyBindings{
			Role:    ib.Role,
			Members: ib.Members,
		})
	}
	return rbs
}

func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy {
	return &iampb.Policy{
		Bindings: iamFromStorageBindings(rp.Bindings),
		Etag:     []byte(rp.Etag),
	}
}

func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding {
	var ibs []*iampb.Binding
	for _, rb := range rbs {
		ibs = append(ibs, &iampb.Binding{
			Role:    rb.Role,
			Members: rb.Members,
		})
	}
	return ibs
}
