import _regeneratorRuntime from "@babel/runtime/regenerator";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import { useMemo } from "react";
import { useAppConfig } from "../../components/AppConfig";
import xmlParser from "fast-xml-parser";
import useIsDesktop from "../../hooks/use-is-desktop";
import { AwsClient } from "aws4fetch";

function parseS3URI(s3Path) {
  var bucket = s3Path.match(/s3:\/\/([^/]+)/)[1];
  var path = s3Path.replace(/s3:\/\/[^/]+\//, "");
  return {
    bucket: bucket,
    path: path
  };
}

export default (function () {
  var _useAppConfig = useAppConfig(),
      appConfig = _useAppConfig.appConfig;

  var isDesktop = useIsDesktop();
  var accessKeyId = appConfig["auth.s3iam.accessKeyId"],
      secretAccessKey = appConfig["auth.s3iam.secretAccessKey"],
      region = appConfig["auth.s3iam.region"],
      corsProxy = appConfig["auth.proxy.corsproxy"];

  if (isDesktop) {
    corsProxy = "{URL}";
  } // TODO if electron don't use CORS proxy


  var awsClient = useMemo(function () {
    return accessKeyId ? new AwsClient({
      accessKeyId: accessKeyId,
      secretAccessKey: secretAccessKey,
      region: region,
      service: "s3"
    }) : null;
  }, // eslint-disable-next-line
  []);

  var fetchS3 = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(url) {
      var opts,
          request,
          corsProxyRequest,
          response,
          _args = arguments;
      return _regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              opts = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
              _context.next = 3;
              return awsClient.sign(url, opts);

            case 3:
              request = _context.sent;
              corsProxyRequest = new Request(corsProxy.replace("{URL}", encodeURIComponent(request.url)), {
                headers: request.headers,
                method: request.method,
                body: opts.body
              });
              _context.next = 7;
              return fetch(corsProxyRequest).then(function (r) {
                return r.text();
              });

            case 7:
              response = _context.sent;
              return _context.abrupt("return", xmlParser.parse(response));

            case 9:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    return function fetchS3(_x) {
      return _ref.apply(this, arguments);
    };
  }();

  if (!accessKeyId) return {};
  return useMemo(function () {
    return {
      parseS3URI: parseS3URI,
      listBuckets: function listBuckets() {
        return fetchS3("https://s3.amazonaws.com");
      },
      listBucketItemsAt: function listBucketItemsAt(s3Path) {
        var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

        var _parseS3URI = parseS3URI(s3Path),
            bucket = _parseS3URI.bucket,
            path = _parseS3URI.path;

        return fetchS3("https://s3.".concat(region, ".amazonaws.com/").concat(bucket, "?list-type=2&delimiter=/&prefix=").concat(path), {
          headers: {
            Host: bucket
          }
        });
      },
      putBucketItem: function () {
        var _putBucketItem = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(s3Path, file) {
          var _parseS3URI2, bucket, path, res;

          return _regeneratorRuntime.wrap(function _callee2$(_context2) {
            while (1) {
              switch (_context2.prev = _context2.next) {
                case 0:
                  _parseS3URI2 = parseS3URI(s3Path), bucket = _parseS3URI2.bucket, path = _parseS3URI2.path;
                  _context2.next = 3;
                  return fetchS3("https://s3.".concat(region, ".amazonaws.com/").concat(bucket, "/").concat(path), {
                    method: "PUT",
                    headers: {
                      Host: "s3.amazonaws.com/".concat(bucket),
                      "Content-Type": file.type,
                      "x-amz-acl": "public-read"
                    },
                    body: file
                  });

                case 3:
                  res = _context2.sent;

                  if (!res.Error) {
                    _context2.next = 6;
                    break;
                  }

                  throw new Error("".concat(res.Error.Code, ": ").concat(res.Error.Message));

                case 6:
                  return _context2.abrupt("return", res);

                case 7:
                case "end":
                  return _context2.stop();
              }
            }
          }, _callee2);
        }));

        function putBucketItem(_x2, _x3) {
          return _putBucketItem.apply(this, arguments);
        }

        return putBucketItem;
      }()
    };
  }, // eslint-disable-next-line
  [awsClient]);
});