var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "lodash", "../service", "./../spec/spec"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const lodash_1 = require("lodash");
    const service_1 = require("../service");
    const spec_1 = require("./../spec/spec");
    /**
     * @hidden
     */
    const service = service_1.Service(spec_1.S3);
    /**
     * @hidden
     */
    const Bucket = function (name, AWSClient, logical) {
        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
            const versioningPromise = AWSClient
                .getBucketVersioning({ Bucket: name })
                .promise();
            const corsPromise = AWSClient
                .getBucketCors({ Bucket: name })
                .promise()
                .then(data => {
                const corsresult = { CORSRules: [] };
                corsresult.CORSRules = data.CORSRules.map(c => {
                    const x = { MaxAge: 0 };
                    x.MaxAge = c.MaxAgeSeconds;
                    return x;
                });
                return corsresult;
            })
                .catch(e => {
                // Silently catch the NoSuchCORSConfiguration
                return { CORSRules: null };
            });
            const lifecyclePromise = AWSClient
                .getBucketLifecycleConfiguration({ Bucket: name })
                .promise()
                .then(data => data)
                .catch(e => {
                // Silently catch the NoSuchLifecycleConfiguration
                return null;
            });
            const loggingPromise = AWSClient.getBucketLogging({ Bucket: name }).promise();
            const notificationPromise = AWSClient
                .getBucketNotification({ Bucket: name })
                .promise();
            const replicationPromise = AWSClient
                .getBucketReplication({ Bucket: name })
                .promise()
                .then(data => data)
                .catch(e => {
                // Silently catch the ReplicationConfigurationNotFoundError
                return null;
            });
            const taggingPromise = AWSClient
                .getBucketTagging({
                Bucket: name
            })
                .promise()
                .then(data => data)
                .catch(e => {
                // Silently catch the NoSuchTagSet
                return null;
            });
            const websitePromise = AWSClient
                .getBucketWebsite({ Bucket: name })
                .promise()
                .then(data => data)
                .catch(e => {
                // Silently catch the NoSuchWebsiteConfiguration
                return null;
            });
            const accessControlPromise = AWSClient
                .getBucketAcl({ Bucket: name })
                .promise();
            const acceleratePromise = AWSClient
                .getBucketAccelerateConfiguration({ Bucket: name })
                .promise();
            const analyticsPromise = AWSClient
                .listBucketAnalyticsConfigurations({ Bucket: name })
                .promise();
            const inventoryPromise = AWSClient
                .listBucketInventoryConfigurations({ Bucket: name })
                .promise();
            const metricsPromise = AWSClient
                .listBucketMetricsConfigurations({ Bucket: name })
                .promise();
            const [versionResults, corsResults, lifecycleResults, loggingResults, notificationResults, replicationResults, taggingResults, websiteResults, accessControlResults, accelerateResults, analyticsResults, inventoryResults, metricsResults] = yield Promise.all([
                versioningPromise,
                corsPromise,
                lifecyclePromise,
                loggingPromise,
                notificationPromise,
                replicationPromise,
                taggingPromise,
                websitePromise,
                accessControlPromise,
                acceleratePromise,
                analyticsPromise,
                inventoryPromise,
                metricsPromise
            ]);
            const resource = { BucketName: name };
            if (versionResults.Status) {
                resource.VersioningConfiguration = versionResults;
            }
            if (corsResults.CORSRules) {
                resource.CorsConfiguration = { CORSRules: corsResults.CORSRules };
            }
            if (lifecycleResults) {
                resource.LifecycleConfiguration = lifecycleResults;
            }
            if (loggingResults && loggingResults.LoggingEnabled) {
                resource.LoggingConfiguration = {
                    DestinationBucketName: loggingResults.LoggingEnabled.TargetBucket,
                    LogFilePrefix: loggingResults.LoggingEnabled.TargetPrefix
                };
            }
            if (Object.keys(notificationResults).length > 0) {
                resource.NotificationConfiguration = notificationResults;
            }
            if (replicationResults) {
                resource.ReplicationConfiguration = replicationResults;
            }
            if (taggingResults) {
                resource.Tags = taggingResults.TagSet;
            }
            if (websiteResults) {
                resource.WebsiteConfiguration = websiteResults;
            }
            if (accessControlResults) {
                resource.AccessControl = accessControlResults;
            }
            if (accelerateResults) {
                resource.AccelerateConfiguration = accelerateResults;
            }
            if (analyticsResults) {
                resource.AnalyticsConfigurations =
                    analyticsResults.AnalyticsConfigurationList;
            }
            if (inventoryResults) {
                resource.InventoryConfigurations =
                    inventoryResults.InventoryConfigurationList;
            }
            if (metricsResults) {
                resource.MetricsConfigurations = metricsResults.MetricsConfigurationList;
            }
            return resolve(service.Bucket(logical, resource));
        }));
    };
    /**
     * @hidden
     */
    const BucketList = function (AWSClient) {
        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
            const { Buckets } = yield AWSClient.listBuckets().promise();
            const list = yield Promise.all(Buckets.map(b => Bucket(b.Name, AWSClient, `${b.Name}S3Bucket`)));
            resolve(list);
        }));
    };
    /**
     * @hidden
     */
    const BucketPolicy = function (name, AWSClient, logical) {
        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
            try {
                const { Policy } = yield AWSClient
                    .getBucketPolicy({ Bucket: name })
                    .promise();
                const resource = {
                    Bucket: name,
                    PolicyDocument: Policy
                };
                resolve(service.BucketPolicy(logical, resource));
            }
            catch (e) {
                // Silently catch Error: The bucket policy does not exist
                resolve(undefined);
            }
        }));
    };
    /**
     * @hidden
     */
    const BucketPolicyList = function (AWSClient) {
        return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
            const { Buckets } = yield AWSClient.listBuckets().promise();
            let list = yield Promise.all(Buckets.map(b => BucketPolicy(b.Name, AWSClient, `${b.Name}S3BucketPolicy`)));
            list = lodash_1.compact(list);
            resolve(list);
        }));
    };
    /**
     * @hidden
     */
    exports.S3 = {
        Bucket,
        BucketList,
        BucketPolicy,
        BucketPolicyList
    };
});
//# sourceMappingURL=S3.js.map