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"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// BlobStorageClient contains operations for Microsoft Azure Blob Storage
// Service.
type BlobStorageClient struct {
	client Client
	auth   authentication
}

// GetServiceProperties gets the properties of your storage account's blob service.
// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-service-properties
func (b *BlobStorageClient) GetServiceProperties() (*ServiceProperties, error) {
	return b.client.getServiceProperties(blobServiceName, b.auth)
}

// SetServiceProperties sets the properties of your storage account's blob service.
// See: https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-blob-service-properties
func (b *BlobStorageClient) SetServiceProperties(props ServiceProperties) error {
	return b.client.setServiceProperties(props, blobServiceName, b.auth)
}

// ListContainersParameters defines the set of customizable parameters to make a
// List Containers call.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx
type ListContainersParameters struct {
	Prefix     string
	Marker     string
	Include    string
	MaxResults uint
	Timeout    uint
}

// GetContainerReference returns a Container object for the specified container name.
func (b *BlobStorageClient) GetContainerReference(name string) *Container {
	return &Container{
		bsc:  b,
		Name: name,
	}
}

// GetContainerReferenceFromSASURI returns a Container object for the specified
// container SASURI
func GetContainerReferenceFromSASURI(sasuri url.URL) (*Container, error) {
	path := strings.Split(sasuri.Path, "/")
	if len(path) <= 1 {
		return nil, fmt.Errorf("could not find a container in URI: %s", sasuri.String())
	}
	c, err := newSASClientFromURL(&sasuri)
	if err != nil {
		return nil, err
	}
	cli := c.GetBlobService()
	return &Container{
		bsc:    &cli,
		Name:   path[1],
		sasuri: sasuri,
	}, nil
}

// ListContainers returns the list of containers in a storage account along with
// pagination token and other response details.
//
// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx
func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*ContainerListResponse, error) {
	q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}})
	uri := b.client.getEndpoint(blobServiceName, "", q)
	headers := b.client.getStandardHeaders()

	type ContainerAlias struct {
		bsc        *BlobStorageClient
		Name       string              `xml:"Name"`
		Properties ContainerProperties `xml:"Properties"`
		Metadata   BlobMetadata
		sasuri     url.URL
	}
	type ContainerListResponseAlias 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 []ContainerAlias `xml:"Containers>Container"`
	}

	var outAlias ContainerListResponseAlias
	resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	err = xmlUnmarshal(resp.Body, &outAlias)
	if err != nil {
		return nil, err
	}

	out := ContainerListResponse{
		XMLName:    outAlias.XMLName,
		Xmlns:      outAlias.Xmlns,
		Prefix:     outAlias.Prefix,
		Marker:     outAlias.Marker,
		NextMarker: outAlias.NextMarker,
		MaxResults: outAlias.MaxResults,
		Containers: make([]Container, len(outAlias.Containers)),
	}
	for i, cnt := range outAlias.Containers {
		out.Containers[i] = Container{
			bsc:        &b,
			Name:       cnt.Name,
			Properties: cnt.Properties,
			Metadata:   map[string]string(cnt.Metadata),
			sasuri:     cnt.sasuri,
		}
	}

	return &out, err
}

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

	if p.Prefix != "" {
		out.Set("prefix", p.Prefix)
	}
	if p.Marker != "" {
		out.Set("marker", p.Marker)
	}
	if p.Include != "" {
		out.Set("include", p.Include)
	}
	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 writeMetadata(h http.Header) map[string]string {
	metadata := make(map[string]string)
	for k, v := range h {
		// Can't trust CanonicalHeaderKey() to munge case
		// reliably. "_" is allowed in identifiers:
		// https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
		// https://msdn.microsoft.com/library/aa664670(VS.71).aspx
		// http://tools.ietf.org/html/rfc7230#section-3.2
		// ...but "_" is considered invalid by
		// CanonicalMIMEHeaderKey in
		// https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
		// so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl".
		k = strings.ToLower(k)
		if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
			continue
		}
		// metadata["lol"] = content of the last X-Ms-Meta-Lol header
		k = k[len(userDefinedMetadataHeaderPrefix):]
		metadata[k] = v[len(v)-1]
	}
	return metadata
}
