package storage

// Copyright 2017 Microsoft Corporation
//
//  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.

import (
	"encoding/xml"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

// Container represents an Azure container.
type Container struct {
	bsc        *BlobStorageClient
	Name       string              `xml:"Name"`
	Properties ContainerProperties `xml:"Properties"`
	Metadata   map[string]string
	sasuri     url.URL
}

// Client returns the HTTP client used by the Container reference.
func (c *Container) Client() *Client {
	return &c.bsc.client
}

func (c *Container) buildPath() string {
	return fmt.Sprintf("/%s", c.Name)
}

// GetURL gets the canonical URL to the container.
// This method does not create a publicly accessible URL if the container
// is private and this method does not check if the blob exists.
func (c *Container) GetURL() string {
	container := c.Name
	if container == "" {
		container = "$root"
	}
	return c.bsc.client.getEndpoint(blobServiceName, pathForResource(container, ""), nil)
}

// ContainerSASOptions are options to construct a container SAS
// URI.
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
type ContainerSASOptions struct {
	ContainerSASPermissions
	OverrideHeaders
	SASOptions
}

// ContainerSASPermissions includes the available permissions for
// a container SAS URI.
type ContainerSASPermissions struct {
	BlobServiceSASPermissions
	List bool
}

// GetSASURI creates an URL to the container which contains the Shared
// Access Signature with the specified options.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
func (c *Container) GetSASURI(options ContainerSASOptions) (string, error) {
	uri := c.GetURL()
	signedResource := "c"
	canonicalizedResource, err := c.bsc.client.buildCanonicalizedResource(uri, c.bsc.auth, true)
	if err != nil {
		return "", err
	}

	// build permissions string
	permissions := options.BlobServiceSASPermissions.buildString()
	if options.List {
		permissions += "l"
	}

	return c.bsc.client.blobAndFileSASURI(options.SASOptions, uri, permissions, canonicalizedResource, signedResource, options.OverrideHeaders)
}

// ContainerProperties contains various properties of a container returned from
// various endpoints like ListContainers.
type ContainerProperties struct {
	LastModified  string              `xml:"Last-Modified"`
	Etag          string              `xml:"Etag"`
	LeaseStatus   string              `xml:"LeaseStatus"`
	LeaseState    string              `xml:"LeaseState"`
	LeaseDuration string              `xml:"LeaseDuration"`
	PublicAccess  ContainerAccessType `xml:"PublicAccess"`
}

// ContainerListResponse contains the response fields from
// ListContainers call.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx
type ContainerListResponse struct {
	XMLName    xml.Name    `xml:"EnumerationResults"`
	Xmlns      string      `xml:"xmlns,attr"`
	Prefix     string      `xml:"Prefix"`
	Marker     string      `xml:"Marker"`
	NextMarker string      `xml:"NextMarker"`
	MaxResults int64       `xml:"MaxResults"`
	Containers []Container `xml:"Containers>Container"`
}

// BlobListResponse contains the response fields from ListBlobs call.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx
type BlobListResponse struct {
	XMLName    xml.Name `xml:"EnumerationResults"`
	Xmlns      string   `xml:"xmlns,attr"`
	Prefix     string   `xml:"Prefix"`
	Marker     string   `xml:"Marker"`
	NextMarker string   `xml:"NextMarker"`
	MaxResults int64    `xml:"MaxResults"`
	Blobs      []Blob   `xml:"Blobs>Blob"`

	// BlobPrefix is used to traverse blobs as if it were a file system.
	// It is returned if ListBlobsParameters.Delimiter is specified.
	// The list here can be thought of as "folders" that may contain
	// other folders or blobs.
	BlobPrefixes []string `xml:"Blobs>BlobPrefix>Name"`

	// Delimiter is used to traverse blobs as if it were a file system.
	// It is returned if ListBlobsParameters.Delimiter is specified.
	Delimiter string `xml:"Delimiter"`
}

// IncludeBlobDataset has options to include in a list blobs operation
type IncludeBlobDataset struct {
	Snapshots        bool
	Metadata         bool
	UncommittedBlobs bool
	Copy             bool
}

// ListBlobsParameters defines the set of customizable
// parameters to make a List Blobs call.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd135734.aspx
type ListBlobsParameters struct {
	Prefix     string
	Delimiter  string
	Marker     string
	Include    *IncludeBlobDataset
	MaxResults uint
	Timeout    uint
	RequestID  string
}

func (p ListBlobsParameters) getParameters() url.Values {
	out := url.Values{}

	if p.Prefix != "" {
		out.Set("prefix", p.Prefix)
	}
	if p.Delimiter != "" {
		out.Set("delimiter", p.Delimiter)
	}
	if p.Marker != "" {
		out.Set("marker", p.Marker)
	}
	if p.Include != nil {
		include := []string{}
		include = addString(include, p.Include.Snapshots, "snapshots")
		include = addString(include, p.Include.Metadata, "metadata")
		include = addString(include, p.Include.UncommittedBlobs, "uncommittedblobs")
		include = addString(include, p.Include.Copy, "copy")
		fullInclude := strings.Join(include, ",")
		out.Set("include", fullInclude)
	}
	if p.MaxResults != 0 {
		out.Set("maxresults", strconv.FormatUint(uint64(p.MaxResults), 10))
	}
	if p.Timeout != 0 {
		out.Set("timeout", strconv.FormatUint(uint64(p.Timeout), 10))
	}

	return out
}

func addString(datasets []string, include bool, text string) []string {
	if include {
		datasets = append(datasets, text)
	}
	return datasets
}

// ContainerAccessType defines the access level to the container from a public
// request.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd179468.aspx and "x-ms-
// blob-public-access" header.
type ContainerAccessType string

// Access options for containers
const (
	ContainerAccessTypePrivate   ContainerAccessType = ""
	ContainerAccessTypeBlob      ContainerAccessType = "blob"
	ContainerAccessTypeContainer ContainerAccessType = "container"
)

// ContainerAccessPolicy represents each access policy in the container ACL.
type ContainerAccessPolicy struct {
	ID         string
	StartTime  time.Time
	ExpiryTime time.Time
	CanRead    bool
	CanWrite   bool
	CanDelete  bool
}

// ContainerPermissions represents the container ACLs.
type ContainerPermissions struct {
	AccessType     ContainerAccessType
	AccessPolicies []ContainerAccessPolicy
}

// ContainerAccessHeader references header used when setting/getting container ACL
const (
	ContainerAccessHeader string = "x-ms-blob-public-access"
)

// GetBlobReference returns a Blob object for the specified blob name.
func (c *Container) GetBlobReference(name string) *Blob {
	return &Blob{
		Container: c,
		Name:      name,
	}
}

// CreateContainerOptions includes the options for a create container operation
type CreateContainerOptions struct {
	Timeout   uint
	Access    ContainerAccessType `header:"x-ms-blob-public-access"`
	RequestID string              `header:"x-ms-client-request-id"`
}

// Create creates a blob container within the storage account
// with given name and access level. Returns error if container already exists.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Container
func (c *Container) Create(options *CreateContainerOptions) error {
	resp, err := c.create(options)
	if err != nil {
		return err
	}
	defer drainRespBody(resp)
	return checkRespCode(resp, []int{http.StatusCreated})
}

// CreateIfNotExists creates a blob container if it does not exist. Returns
// true if container is newly created or false if container already exists.
func (c *Container) CreateIfNotExists(options *CreateContainerOptions) (bool, error) {
	resp, err := c.create(options)
	if resp != nil {
		defer drainRespBody(resp)
		if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
			return resp.StatusCode == http.StatusCreated, nil
		}
	}
	return false, err
}

func (c *Container) create(options *CreateContainerOptions) (*http.Response, error) {
	query := url.Values{"restype": {"container"}}
	headers := c.bsc.client.getStandardHeaders()
	headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata)

	if options != nil {
		query = addTimeout(query, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), query)

	return c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth)
}

// Exists returns true if a container with given name exists
// on the storage account, otherwise returns false.
func (c *Container) Exists() (bool, error) {
	q := url.Values{"restype": {"container"}}
	var uri string
	if c.bsc.client.isServiceSASClient() {
		q = mergeParams(q, c.sasuri.Query())
		newURI := c.sasuri
		newURI.RawQuery = q.Encode()
		uri = newURI.String()

	} else {
		uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
	}
	headers := c.bsc.client.getStandardHeaders()

	resp, err := c.bsc.client.exec(http.MethodHead, uri, headers, nil, c.bsc.auth)
	if resp != nil {
		defer drainRespBody(resp)
		if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
			return resp.StatusCode == http.StatusOK, nil
		}
	}
	return false, err
}

// SetContainerPermissionOptions includes options for a set container permissions operation
type SetContainerPermissionOptions struct {
	Timeout           uint
	LeaseID           string     `header:"x-ms-lease-id"`
	IfModifiedSince   *time.Time `header:"If-Modified-Since"`
	IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"`
	RequestID         string     `header:"x-ms-client-request-id"`
}

// SetPermissions sets up container permissions
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Container-ACL
func (c *Container) SetPermissions(permissions ContainerPermissions, options *SetContainerPermissionOptions) error {
	body, length, err := generateContainerACLpayload(permissions.AccessPolicies)
	if err != nil {
		return err
	}
	params := url.Values{
		"restype": {"container"},
		"comp":    {"acl"},
	}
	headers := c.bsc.client.getStandardHeaders()
	headers = addToHeaders(headers, ContainerAccessHeader, string(permissions.AccessType))
	headers["Content-Length"] = strconv.Itoa(length)

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)

	resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, body, c.bsc.auth)
	if err != nil {
		return err
	}
	defer drainRespBody(resp)
	return checkRespCode(resp, []int{http.StatusOK})
}

// GetContainerPermissionOptions includes options for a get container permissions operation
type GetContainerPermissionOptions struct {
	Timeout   uint
	LeaseID   string `header:"x-ms-lease-id"`
	RequestID string `header:"x-ms-client-request-id"`
}

// GetPermissions gets the container permissions as per https://msdn.microsoft.com/en-us/library/azure/dd179469.aspx
// If timeout is 0 then it will not be passed to Azure
// leaseID will only be passed to Azure if populated
func (c *Container) GetPermissions(options *GetContainerPermissionOptions) (*ContainerPermissions, error) {
	params := url.Values{
		"restype": {"container"},
		"comp":    {"acl"},
	}
	headers := c.bsc.client.getStandardHeaders()

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)

	resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var ap AccessPolicy
	err = xmlUnmarshal(resp.Body, &ap.SignedIdentifiersList)
	if err != nil {
		return nil, err
	}
	return buildAccessPolicy(ap, &resp.Header), nil
}

func buildAccessPolicy(ap AccessPolicy, headers *http.Header) *ContainerPermissions {
	// containerAccess. Blob, Container, empty
	containerAccess := headers.Get(http.CanonicalHeaderKey(ContainerAccessHeader))
	permissions := ContainerPermissions{
		AccessType:     ContainerAccessType(containerAccess),
		AccessPolicies: []ContainerAccessPolicy{},
	}

	for _, policy := range ap.SignedIdentifiersList.SignedIdentifiers {
		capd := ContainerAccessPolicy{
			ID:         policy.ID,
			StartTime:  policy.AccessPolicy.StartTime,
			ExpiryTime: policy.AccessPolicy.ExpiryTime,
		}
		capd.CanRead = updatePermissions(policy.AccessPolicy.Permission, "r")
		capd.CanWrite = updatePermissions(policy.AccessPolicy.Permission, "w")
		capd.CanDelete = updatePermissions(policy.AccessPolicy.Permission, "d")

		permissions.AccessPolicies = append(permissions.AccessPolicies, capd)
	}
	return &permissions
}

// DeleteContainerOptions includes options for a delete container operation
type DeleteContainerOptions struct {
	Timeout           uint
	LeaseID           string     `header:"x-ms-lease-id"`
	IfModifiedSince   *time.Time `header:"If-Modified-Since"`
	IfUnmodifiedSince *time.Time `header:"If-Unmodified-Since"`
	RequestID         string     `header:"x-ms-client-request-id"`
}

// Delete deletes the container with given name on the storage
// account. If the container does not exist returns error.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/delete-container
func (c *Container) Delete(options *DeleteContainerOptions) error {
	resp, err := c.delete(options)
	if err != nil {
		return err
	}
	defer drainRespBody(resp)
	return checkRespCode(resp, []int{http.StatusAccepted})
}

// DeleteIfExists deletes the container with given name on the storage
// account if it exists. Returns true if container is deleted with this call, or
// false if the container did not exist at the time of the Delete Container
// operation.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/delete-container
func (c *Container) DeleteIfExists(options *DeleteContainerOptions) (bool, error) {
	resp, err := c.delete(options)
	if resp != nil {
		defer drainRespBody(resp)
		if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
			return resp.StatusCode == http.StatusAccepted, nil
		}
	}
	return false, err
}

func (c *Container) delete(options *DeleteContainerOptions) (*http.Response, error) {
	query := url.Values{"restype": {"container"}}
	headers := c.bsc.client.getStandardHeaders()

	if options != nil {
		query = addTimeout(query, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), query)

	return c.bsc.client.exec(http.MethodDelete, uri, headers, nil, c.bsc.auth)
}

// ListBlobs returns an object that contains list of blobs in the container,
// pagination token and other information in the response of List Blobs call.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/List-Blobs
func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, error) {
	q := mergeParams(params.getParameters(), url.Values{
		"restype": {"container"},
		"comp":    {"list"},
	})
	var uri string
	if c.bsc.client.isServiceSASClient() {
		q = mergeParams(q, c.sasuri.Query())
		newURI := c.sasuri
		newURI.RawQuery = q.Encode()
		uri = newURI.String()
	} else {
		uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
	}

	headers := c.bsc.client.getStandardHeaders()
	headers = addToHeaders(headers, "x-ms-client-request-id", params.RequestID)

	var out BlobListResponse
	resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
	if err != nil {
		return out, err
	}
	defer resp.Body.Close()

	err = xmlUnmarshal(resp.Body, &out)
	for i := range out.Blobs {
		out.Blobs[i].Container = c
	}
	return out, err
}

// ContainerMetadataOptions includes options for container metadata operations
type ContainerMetadataOptions struct {
	Timeout   uint
	LeaseID   string `header:"x-ms-lease-id"`
	RequestID string `header:"x-ms-client-request-id"`
}

// SetMetadata replaces the metadata for the specified container.
//
// Some keys may be converted to Camel-Case before sending. All keys
// are returned in lower case by GetBlobMetadata. HTTP header names
// are case-insensitive so case munging should not matter to other
// applications either.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-metadata
func (c *Container) SetMetadata(options *ContainerMetadataOptions) error {
	params := url.Values{
		"comp":    {"metadata"},
		"restype": {"container"},
	}
	headers := c.bsc.client.getStandardHeaders()
	headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata)

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}

	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)

	resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth)
	if err != nil {
		return err
	}
	defer drainRespBody(resp)
	return checkRespCode(resp, []int{http.StatusOK})
}

// GetMetadata returns all user-defined metadata for the specified container.
//
// All metadata keys will be returned in lower case. (HTTP header
// names are case-insensitive.)
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-metadata
func (c *Container) GetMetadata(options *ContainerMetadataOptions) error {
	params := url.Values{
		"comp":    {"metadata"},
		"restype": {"container"},
	}
	headers := c.bsc.client.getStandardHeaders()

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}

	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)

	resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
	if err != nil {
		return err
	}
	defer drainRespBody(resp)
	if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
		return err
	}

	c.writeMetadata(resp.Header)
	return nil
}

func (c *Container) writeMetadata(h http.Header) {
	c.Metadata = writeMetadata(h)
}

func generateContainerACLpayload(policies []ContainerAccessPolicy) (io.Reader, int, error) {
	sil := SignedIdentifiers{
		SignedIdentifiers: []SignedIdentifier{},
	}
	for _, capd := range policies {
		permission := capd.generateContainerPermissions()
		signedIdentifier := convertAccessPolicyToXMLStructs(capd.ID, capd.StartTime, capd.ExpiryTime, permission)
		sil.SignedIdentifiers = append(sil.SignedIdentifiers, signedIdentifier)
	}
	return xmlMarshal(sil)
}

func (capd *ContainerAccessPolicy) generateContainerPermissions() (permissions string) {
	// generate the permissions string (rwd).
	// still want the end user API to have bool flags.
	permissions = ""

	if capd.CanRead {
		permissions += "r"
	}

	if capd.CanWrite {
		permissions += "w"
	}

	if capd.CanDelete {
		permissions += "d"
	}

	return permissions
}

// GetProperties updated the properties of the container.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-properties
func (c *Container) GetProperties() error {
	params := url.Values{
		"restype": {"container"},
	}
	headers := c.bsc.client.getStandardHeaders()

	uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)

	resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
		return err
	}

	// update properties
	c.Properties.Etag = resp.Header.Get(headerEtag)
	c.Properties.LeaseStatus = resp.Header.Get("x-ms-lease-status")
	c.Properties.LeaseState = resp.Header.Get("x-ms-lease-state")
	c.Properties.LeaseDuration = resp.Header.Get("x-ms-lease-duration")
	c.Properties.LastModified = resp.Header.Get("Last-Modified")
	c.Properties.PublicAccess = ContainerAccessType(resp.Header.Get(ContainerAccessHeader))

	return nil
}
