System.register(["reactive-jsx", "src/client/poid.js", "src/external/focalStorage.js", "utils"], function (_export, _context) {
  "use strict";

  var _addSourceLocation, _attributeStringLiteral, _childExpression, _childSpread, _childElement, _children, _attributes, _element, Scheme, PolymorphicIdentifier, focalStorage, parseQuery, getDeepProperty;

  return {
    setters: [function (_reactiveJsx) {
      _addSourceLocation = _reactiveJsx.addSourceLocation;
      _attributeStringLiteral = _reactiveJsx.attributeStringLiteral;
      _childExpression = _reactiveJsx.childExpression;
      _childSpread = _reactiveJsx.childSpread;
      _childElement = _reactiveJsx.childElement;
      _children = _reactiveJsx.children;
      _attributes = _reactiveJsx.attributes;
      _element = _reactiveJsx.element;
    }, function (_srcClientPoidJs) {
      Scheme = _srcClientPoidJs.Scheme;
      PolymorphicIdentifier = _srcClientPoidJs.default;
    }, function (_srcExternalFocalStorageJs) {
      focalStorage = _srcExternalFocalStorageJs.default;
    }, function (_utils) {
      parseQuery = _utils.parseQuery;
      getDeepProperty = _utils.getDeepProperty;
    }],
    execute: function () {
      const __SystemJSRewritingHack = {};
      _recorder_._demos_plex_plex_scheme_js = _recorder_._demos_plex_plex_scheme_js || {};
      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "Scheme", {
        get() {
          return Scheme;
        },

        set(thisIsVererySecretVariableName) {
          Scheme = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "PolymorphicIdentifier", {
        get() {
          return PolymorphicIdentifier;
        },

        set(thisIsVererySecretVariableName) {
          PolymorphicIdentifier = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "focalStorage", {
        get() {
          return focalStorage;
        },

        set(thisIsVererySecretVariableName) {
          focalStorage = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "getDeepProperty", {
        get() {
          return getDeepProperty;
        },

        set(thisIsVererySecretVariableName) {
          getDeepProperty = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "parseQuery", {
        get() {
          return parseQuery;
        },

        set(thisIsVererySecretVariableName) {
          parseQuery = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });


      var lastTokenPromted = _recorder_._demos_plex_plex_scheme_js.lastTokenPromted;

      // focalStorage.getItem("plex-token")
      // focalStorage.setItem("plex-token", undefined)

      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "lastTokenPromted", {
        get() {
          return lastTokenPromted;
        },

        set(thisIsVererySecretVariableName) {
          lastTokenPromted = thisIsVererySecretVariableName;
          return true;
        },

        enumerable: true,
        configurable: true
      });
      class PlexScheme extends Scheme {

        get scheme() {
          return "plex";
        }

        async plexToken() {
          var token = await focalStorage.getItem("plex-token");
          if (!token && (!lastTokenPromted || Date.now() - lastTokenPromted > 1000 * 5)) {
            // don't ask again for 5 seconds...
            _recorder_._demos_plex_plex_scheme_js.lastTokenPromted = Date.now();
            token = await lively.prompt("plex token required: ");
            if (token) {
              focalStorage.setItem("plex-token", token);
            }
          }
          return token;
        }

        resolve() {
          return true;
        }

        plexChildren(mediacontent) {
          return Array.from(mediacontent.childNodes).filter(ea => ea.getAttribute);
        }

        plexToJSON(mediacontent) {

          let obj = {
            _type: mediacontent.tagName
          };
          mediacontent.getAttributeNames().forEach(prop => {
            obj[prop] = mediacontent.getAttribute(prop);
          });

          this.plexChildren(mediacontent).forEach(child => {

            let tag = child.getAttribute("tag");
            if (tag) {
              if (!obj[child.tagName]) obj[child.tagName] = [];
              obj[child.tagName].push(tag);
            } else if (child.tagName == "Media") {
              if (!obj.media) obj.media = [];
              obj.media.push(this.plexToJSON(child));
            } else if (child.tagName == "Part") {
              if (!obj.part) obj.part = [];
              obj.part.push(this.plexToJSON(child));
            } else {
              if (!obj.children) obj.children = [];
              obj.children.push(this.plexToJSON(child));
            }

            // if (prop.tagName == "Media") {
            //   this.plexChildren(mediacontent)[0].getAttribute("file")
            // }
          });

          return obj;
        }

        async GET(options) {
          let apiString = this.getAPIString();
          let query = this.getURLQuery();
          let contentType = options && options.headers && new Headers(options.headers).get("content-type");

          let html;
          let mediacontent = await this.plex(apiString);

          let htmlResponse = function (html) {
            return new Response(html.outerHTML, {
              status: 200,
              headers: {
                "content-type": "text/html"
              }
            });
          };

          if (query.json || contentType == 'application/json') {
            // ok, we parse, then serialize, then pase again... can we avoid this?
            return new Response(JSON.stringify(this.plexToJSON(mediacontent)), { status: 200 });
          } else if (query.list) {
            let children = _.sortBy(this.plexChildren(mediacontent), ea => ea.getAttribute("title"));
            html = _element("html", _attributes(), _children(_childElement(_element("ul", _attributes(), _children(_childSpread(children.map(ea => _element("li", _attributes(), _children(_childExpression(ea.getAttribute("title"))), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 43,
                line: 95
              },
              start: {
                column: 8,
                line: 95
              }
            })))), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 14,
                line: 96
              },
              start: {
                column: 19,
                line: 94
              }
            }))), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 21,
                line: 96
              },
              start: {
                column: 13,
                line: 94
              }
            });
            return htmlResponse(html);
          } else if (query.thumbs) {
            let children = _.sortBy(this.plexChildren(mediacontent), ea => ea.getAttribute("title")
            // #TODO we should do this only if we have a thumb        
            );html = _element("html", _attributes(), _children(_childElement(_element("div", _attributes(_attributeStringLiteral("style", "")), _children(_childSpread(children.map(ea => {
              var img = _element("img", _attributes(_attributeStringLiteral("style", ""), _attributeStringLiteral("width", "100px")), _children(), {
                file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
                end: {
                  column: 56,
                  line: 102
                },
                start: {
                  column: 22,
                  line: 102
                }
              });
              img.src = lively.swxURL("plex://" + ea.getAttribute("thumb"));
              img.title = ea.getAttribute("title");
              var a = _element("a", _attributes(_attributeStringLiteral("style", "")), _children(_childExpression(img), _childElement(_element("br", _attributes(), _children(), {
                file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
                end: {
                  column: 43,
                  line: 105
                },
                start: {
                  column: 37,
                  line: 105
                }
              })), _childExpression(ea.getAttribute("title"))), {
                file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
                end: {
                  column: 73,
                  line: 105
                },
                start: {
                  column: 20,
                  line: 105
                }
              });
              a.href = lively.swxURL("plex://" + ea.getAttribute("key"));
              var div = _element("div", _attributes(_attributeStringLiteral("style", "font-size:8pt;margin:10px;vertical-align: text-top; display:inline-block; width:100px; overflow: hidden")), _children(_childExpression(a), _childElement(_element("br", _attributes(), _children(), {
                file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
                end: {
                  column: 148,
                  line: 107
                },
                start: {
                  column: 142,
                  line: 107
                }
              })), _childExpression(ea.getAttribute("year"))), {
                file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
                end: {
                  column: 179,
                  line: 107
                },
                start: {
                  column: 22,
                  line: 107
                }
              });
              return div;
            }))), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 15,
                line: 110
              },
              start: {
                column: 19,
                line: 101
              }
            }))), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 22,
                line: 110
              },
              start: {
                column: 13,
                line: 101
              }
            });
            return htmlResponse(html);
          } else if (query.table) {
            // default html rendering
            let table = await _addSourceLocation(lively.create("lively-table"), {
              file: 'https://lively-kernel.org/lively4/composed-offset/demos/plex/plex-scheme.js',
              end: {
                column: 53,
                line: 114
              },
              start: {
                column: 24,
                line: 114
              }
            });
            try {
              table.setFromJSO(this.plexToJSON(mediacontent).children);
            } finally {
              table.remove();
            }
            html = table;
            return htmlResponse(html);
          } else if (query.html || query.index || contentType == 'text/html') {
            html = `<plex-media src='plex:/${apiString}'></plex-media>`; // a fetchy double dispatch 
            return new Response(html);
          } else {
            // default xml
            let resp = await this.plexBlob(apiString);
            return new Response(resp); // {status: 200}   
          }
        }

        async plex(apiString) {
          var token = await this.plexToken();
          var text = await fetch("http://127.0.0.1:32400" + apiString + "?X-Plex-Token=" + token).then(r => r.text());
          return new DOMParser().parseFromString(text, "text/xml").childNodes[0];
        }

        async plexBlob(apiString) {
          var token = await this.plexToken();
          return fetch("http://127.0.0.1:32400" + apiString + "?X-Plex-Token=" + token).then(r => r.blob());
        }

        optionsFromPlex(xml, url) {
          // single vs. collections... how should we do this?
          if (xml.getAttribute && xml.getAttribute("size") == 1 && xml.childNodes[0].tagName !== "directory") {
            xml = Array.from(xml.childNodes).filter(ea => ea.getAttribute)[0];
            lively.notify("take " + xml.childNodes);
          }
          return {
            name: xml.getAttribute("key") || xml.getAttribute("title") || xml.getAttribute("title1") || xml.tagName,
            title: xml.getAttribute("title") || xml.getAttribute("title1"),
            parent: url.replace(/\/[^/]+\/?$/, ""),
            "index-available": true,
            contents: _.sortBy(Array.from(xml.childNodes).filter(ea => ea.getAttribute && ea.getAttribute("key")).map(ea => {
              var obj = {
                name: ea.getAttribute("key").replace(/\/children$/, "/"),
                title: ea.getAttribute("title") || ea.getAttribute("title1"),
                contents: [],
                parent: url,
                type: ea.tagName == "Directory" ? "directory" : "file"
              };
              if (obj.name.match(/^\//)) {
                obj.type = "link"; // symlinks, cross refs... etc
                obj.href = this.scheme + ":/" + obj.name;
              }
              return obj;
            }), ea => ea.title),
            type: "file"
          };
        }

        getAPIString() {
          var urlObj = new URL(this.url);
          return urlObj.pathname.replace(/\/\//g, "/");
        }

        getURLQuery() {
          var urlObj = new URL(this.url);
          var query = parseQuery(urlObj.search);
          Object.keys(query).forEach(ea => {
            if (query[ea] == "") query[ea] = true;
          });
          return query;
        }

        async OPTIONS() {
          var apiString = this.getAPIString();
          var mediacontent = await this.plex(apiString);
          var result = await this.optionsFromPlex(mediacontent, this.url);
          return new Response(JSON.stringify(result), { status: 200 });
        }
      }

      _export("PlexScheme", PlexScheme);

      Object.defineProperty(_recorder_._demos_plex_plex_scheme_js, "PlexScheme", {
        get() {
          return PlexScheme;
        },

        set(thisIsVererySecretVariableName) {
          _export("PlexScheme", PlexScheme = thisIsVererySecretVariableName);

          return true;
        },

        enumerable: true,
        configurable: true
      });
      lively.components.addPersistentCustomTemplatePath("/demos/plex/");

      PolymorphicIdentifier.register(PlexScheme);

      console.warn("LOADED plex");
    }
  };
});