// Generated by CoffeeScript 1.12.7
var BaseMigration, MigrateSkipException,
  extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
  hasProp = {}.hasOwnProperty,
  indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

BaseMigration = (function(superClass) {
  extend(BaseMigration, superClass);

  function BaseMigration() {
    return BaseMigration.__super__.constructor.apply(this, arguments);
  }

  BaseMigration.click = function() {
    var baseMigration;
    ez5.rootMenu.closeMenu();
    baseMigration = new BaseMigration();
    return baseMigration.showDownloadUploadModal();
  };

  BaseMigration.label = function() {
    return "base.migration.button";
  };

  BaseMigration.is_allowed = function() {
    return ez5.session.hasSystemRight("root", "plugin.basemigration.migration");
  };

  BaseMigration.group = function() {
    return "za_other";
  };

  BaseMigration.submenu = function() {
    return "plugins";
  };

  BaseMigration.prototype.log = function(txt) {
    var arg, args, i, len;
    console.debug.apply(console, arguments);
    args = [];
    for (i = 0, len = arguments.length; i < len; i++) {
      arg = arguments[i];
      args.push(arg);
    }
    return this.__console.log(args.join(" "));
  };

  BaseMigration.prototype.showDownloadUploadModal = function() {
    var diag, downloadBtn, fileReader, uploadBtn;
    this.__console = new CUI.Console();
    fileReader = new CUI.FileReader({
      onAdd: (function(_this) {
        return function() {
          return uploadBtn.startSpinner();
        };
      })(this),
      onFail: (function(_this) {
        return function() {
          uploadBtn.stopSpinner();
          return CUI.alert({
            text: $$("base.migration.error.file_upload_failed")
          });
        };
      })(this),
      onDone: (function(_this) {
        return function(frf) {
          var e, uploaded_data;
          uploadBtn.stopSpinner();
          try {
            uploaded_data = JSON.parse(frf.getResult());
            if (uploaded_data.dump_version !== BaseMigration.dumpVersion) {
              CUI.alert({
                text: $$("base.migration.dump_version_not_matching", {
                  version_found: uploaded_data.dump_version || "unknown",
                  version_expected: BaseMigration.dumpVersion
                })
              });
              return;
            }
          } catch (error) {
            e = error;
            CUI.alert({
              text: $$("base.migration.unable_to_parse_file")
            });
            return;
          }
          _this.log($$("base.migration.console.log.filename.md", {
            filename: frf.getFile().name,
            filesize: ez5.format_filesize(frf.getFile().size)
          }));
          diag.destroy();
          _this.presentUploadedData(uploaded_data);
        };
      })(this)
    });
    downloadBtn = new LocaButton({
      loca_key: "base.migration.choice.download",
      disabled: true,
      onClick: (function(_this) {
        return function(ev, btn) {
          _this["export"]();
          return diag.destroy();
        };
      })(this)
    });
    if (ez5.session.isReadOnly()) {
      uploadBtn = new CUI.Button({
        text: $$("base.migration.choice.upload|text"),
        icon: $$("base.migration.choice.upload|icon"),
        disabled: true,
        onClick: (function(_this) {
          return function() {
            console.debug("Upload button clicked in read-only mode");
            return CUI.problem({
              text: $$("base.error.user.read_only_mode")
            });
          };
        })(this)
      });
    } else {
      uploadBtn = new CUI.FileUploadButton({
        fileUpload: fileReader,
        text: $$("base.migration.choice.upload|text"),
        disabled: true,
        multiple: false,
        icon: $$("base.migration.choice.upload|icon")
      });
    }
    diag = new CUI.ConfirmationDialog({
      cancel: true,
      title: $$("base.migration.choice.title"),
      size: "xs",
      "class": "ez5-base-migration-download-upload-modal",
      content: new LocaLabel({
        loca_key: "base.migration.choice.loading"
      }),
      buttons: [downloadBtn, uploadBtn]
    }).show();
    return this.loadBaseData().done((function(_this) {
      return function() {
        _this.log($$("base.migration.console.log.base-data-loaded"));
        if (diag.isDestroyed()) {
          return;
        }
        downloadBtn.enable();
        uploadBtn.enable();
        diag.setText($$("base.migration.choice.info"));
        return diag.autoSize();
      };
    })(this));
  };

  BaseMigration.prototype.getBaseData = function() {
    return this.__baseData;
  };

  BaseMigration.prototype.migrateWhoInData = function(data, where, level) {
    var e, idx, item, key, ref, ret, value;
    if (where == null) {
      where = "";
    }
    if (level == null) {
      level = 0;
    }
    if ((ref = data != null ? data._basetype : void 0) === "group" || ref === "user") {
      try {
        return this.migrateWho(data);
      } catch (error) {
        e = error;
        if (e instanceof MigrateSkipException) {
          this.log($$("base.migration.console.log.where-skipping-who", {
            where: where,
            error: e.getError()
          }));
        }
        throw e;
      }
      return null;
    }
    if (CUI.isArray(data)) {
      idx = 0;
      while (data.length > idx) {
        item = data[idx];
        try {
          ret = this.migrateWhoInData(item, where, level + 1);
          if (ret !== null) {
            data[idx] = ret;
          }
        } catch (error) {
          e = error;
          if (e instanceof MigrateSkipException) {
            data.splice(idx, 1);
            continue;
          }
          throw e;
        }
        idx++;
      }
      return null;
    }
    if (CUI.isPlainObject(data)) {
      for (key in data) {
        value = data[key];
        try {
          ret = this.migrateWhoInData(value, where, level + 1);
          if (ret !== null) {
            data[key] = ret;
          }
        } catch (error) {
          e = error;
          if (e instanceof MigrateSkipException) {
            delete data[key];
            continue;
          }
          throw e;
        }
      }
      return null;
    }
    return null;
  };

  BaseMigration.prototype.migrateTransition = function(transition) {
    var copied_transition, e, i, j, k, l, len, len1, len2, new_tagfilter, new_who, ref, ref1, ref2, who;
    copied_transition = {
      who: []
    };
    ref = ["actions", "comment", "confirm", "objecttype_ids", "operations", "sticky", "type"];
    for (i = 0, len = ref.length; i < len; i++) {
      k = ref[i];
      copied_transition[k] = CUI.util.copyObject(transition[k], true);
    }
    ref1 = ["tagfilter:before", "tagfilter:after"];
    for (j = 0, len1 = ref1.length; j < len1; j++) {
      k = ref1[j];
      if (!transition[k]) {
        continue;
      }
      try {
        new_tagfilter = this.migrateTagFilter(transition[k]);
      } catch (error) {
        e = error;
        if (e instanceof MigrateSkipException) {
          this.log($$("base.migration.console.log.skipping-tag-filter"), {
            error: e.getError()
          });
          new_tagfilter = null;
        } else {
          throw e;
        }
      }
      if (new_tagfilter) {
        copied_transition[k] = new_tagfilter;
      }
    }
    ref2 = transition.who;
    for (l = 0, len2 = ref2.length; l < len2; l++) {
      who = ref2[l];
      try {
        new_who = this.migrateWho(who);
      } catch (error) {
        e = error;
        if (e instanceof MigrateSkipException) {
          this.log($$("base.migration.console.log.skipping-who", {
            error: e.getError()
          }));
          new_who = null;
        } else {
          throw e;
        }
      }
      if (new_who) {
        copied_transition.who.push(new_who);
      }
    }
    if (ez5.version("6")) {
      copied_transition.who_not = transition.who_not || false;
    }
    if (copied_transition.actions) {
      this.migrateWhoInData(copied_transition.actions, "Transition: Actions");
    }
    if (copied_transition.who.length === 0) {
      this.log($$("base.migration.console.log.transition.no-migratable-found.md"));
      console.warn($$("base.migration.console.log.transition.no-migratable-found.md"), transition);
      return void 0;
    }
    return copied_transition;
  };

  BaseMigration.prototype.migrateACL = function(acl) {
    var acl_row, copied_rights, e, i, len;
    copied_rights = [];
    for (i = 0, len = acl.length; i < len; i++) {
      acl_row = acl[i];
      try {
        copied_rights.push(this.migrateACLRow(acl_row));
      } catch (error) {
        e = error;
        if (e instanceof MigrateSkipException) {
          this.log($$("base.migration.console.log.skipping-right", {
            error: e.getError()
          }));
        } else {
          throw e;
        }
      }
    }
    return copied_rights;
  };

  BaseMigration.prototype.migrateACLRow = function(right) {
    var new_right;
    new_right = {
      active: right.active,
      rights: this.migrateRights(right.rights),
      who: this.migrateWho(right.who)
    };
    if (right.tagfilter) {
      new_right.tagfilter = this.migrateTagFilter(right.tagfilter);
    }
    return new_right;
  };

  BaseMigration.prototype.migrateTagFilter = function(tagfilter) {
    var i, j, k, len, len1, new_tagfilter, ref, ref1, tag_id;
    new_tagfilter = {};
    ref = ["all", "any", "not", "changed"];
    for (i = 0, len = ref.length; i < len; i++) {
      k = ref[i];
      if (!tagfilter[k]) {
        continue;
      }
      if (!new_tagfilter[k]) {
        new_tagfilter[k] = [];
      }
      ref1 = tagfilter[k];
      for (j = 0, len1 = ref1.length; j < len1; j++) {
        tag_id = ref1[j];
        new_tagfilter[k].push(this.migrateTagID(tag_id));
      }
    }
    if (CUI.isEmptyObject(new_tagfilter)) {
      return void 0;
    } else {
      return new_tagfilter;
    }
  };

  BaseMigration.prototype.migrateTagID = function(tag_id) {
    var i, len, ref, source_tag, tag;
    source_tag = this.__sourceData._tag_by_id[tag_id];
    ref = this.__baseData._tags;
    for (i = 0, len = ref.length; i < len; i++) {
      tag = ref[i];
      if (tag._tag_identifier === source_tag._tag_identifier) {
        return tag.tag._id;
      }
    }
    throw new MigrateSkipException({
      text: $$("base.migration.exception.tag-not-found.text.md", {
        target: source_tag._tag_identifier
      })
    });
  };

  BaseMigration.prototype.migrateRights = function(rights) {
    return CUI.util.copyObject(rights, true);
  };

  BaseMigration.prototype.migrateWho = function(who) {
    var _who, baseType, baseUser, dn, errorText, group, groups, new_who, ref, ref1, ref2, ref3, sourceUserReference;
    if (ez5.version("6")) {
      if (who.group) {
        group = this.__sourceData.group.find((function(_this) {
          return function(sourceGroup) {
            return sourceGroup.group._id === who.group._id;
          };
        })(this));
        if (group) {
          who.group = group.group;
        }
      }
    }
    _who = AclWho.newInstance(who);
    baseType = who._basetype;
    dn = _who.getDisplayText();
    if (baseType === "group") {
      groups = this.findGroupsByGroup(who);
      if (groups.length === 0) {
        throw new MigrateSkipException({
          text: $$("base.migration.exception.group-not-found.text.md", {
            group: dn
          })
        });
      } else if (groups.length > 1) {
        console.warn("Who:", who, groups);
        throw new MigrateSkipException({
          text: $$("base.migration.exception.group-repeat.text.md", {
            group: dn
          })
        });
      }
      new_who = {
        _basetype: "group",
        group: {
          _id: groups[0].group._id,
          name: groups[0].group.name,
          displayname: groups[0].group.displayname
        }
      };
    } else if (baseType === "user" && ez5.version("6")) {
      sourceUserReference = (ref = this.getSourceData()["user"]) != null ? (ref1 = ref.find((function(_this) {
        return function(source_user) {
          return source_user.user._id === who.user._id;
        };
      })(this))) != null ? (ref2 = ref1.user) != null ? ref2.reference : void 0 : void 0 : void 0;
      if (!sourceUserReference) {
        throw new MigrateSkipException({
          text: $$("base.migration.exception.user-not-found.text.md", {
            user: dn
          })
        });
      }
      baseUser = (ref3 = this.getBaseData()["user"]) != null ? ref3.find((function(_this) {
        return function(base_user) {
          return base_user.user.reference === sourceUserReference;
        };
      })(this)) : void 0;
      if (!baseUser) {
        throw new MigrateSkipException({
          text: $$("base.migration.exception.user-not-found.text.md", {
            user: dn
          })
        });
      }
      new_who = {
        _basetype: "user",
        user: {
          _id: baseUser.user._id,
          reference: baseUser.user.reference
        }
      };
    } else {
      errorText = $$("base.migration.exception.basetype-not-group.text.md", {
        baseType: baseType,
        displayText: CUI.MarkdownInput.escape(dn)
      });
      throw new MigrateSkipException({
        text: errorText
      });
    }
    return new_who;
  };

  BaseMigration.prototype.findGroupsByGroup = function(group_data) {
    var found_groups, group, i, len, ref;
    found_groups = [];
    ref = this.__baseData.group;
    for (i = 0, len = ref.length; i < len; i++) {
      group = ref[i];
      if (group.group.type !== group_data.group.type) {
        continue;
      }
      switch (group.group.type) {
        case "system":
          if ((!ez5.version("6") && group.group.name === group_data.group.name) || (ez5.version("6") && group.group.reference === group_data.group.reference)) {
            found_groups.push(group);
          }
          break;
        case "easydb":
          if (ez5.loca.getBestFrontendValue(group.group.displayname) === ez5.loca.getBestFrontendValue(group_data.group.displayname)) {
            found_groups.push(group);
          }
      }
    }
    return found_groups;
  };

  BaseMigration.prototype.enhanceBaseData = function(baseData) {
    var context, contexts, i, info, j, l, len, len1, len2, len3, m, preset, ref, ref1, ref2, ref3, rights, tag, tag_group_name, taggroup, user, userList;
    baseData._tags = [];
    baseData._utf8_test = "äöüÄÖÜß";
    baseData._tag_by_id = {};
    ref = baseData.tags;
    for (i = 0, len = ref.length; i < len; i++) {
      taggroup = ref[i];
      tag_group_name = ez5.loca.getBestFrontendValue(taggroup.taggroup.displayname);
      ref1 = taggroup._tags;
      for (j = 0, len1 = ref1.length; j < len1; j++) {
        tag = ref1[j];
        tag._tag_identifier = tag_group_name + "." + ez5.loca.getBestFrontendValue(tag.tag.displayname);
        baseData._tags.push(tag);
        baseData._tag_by_id[tag.tag._id] = tag;
      }
    }
    if (baseData.right && !baseData.preset) {
      rights = {};
      contexts = baseData.right;
      for (context in contexts) {
        info = contexts[context];
        if (!info.capabilities.preset || !info.presets) {
          continue;
        }
        rights[context] = [];
        ref2 = info.presets;
        for (l = 0, len2 = ref2.length; l < len2; l++) {
          preset = ref2[l];
          rights[context].push(preset);
        }
      }
      baseData.preset = rights;
      delete baseData.right;
    }
    if (baseData["user"] != null) {
      userList = [];
      ref3 = baseData.user;
      for (m = 0, len3 = ref3.length; m < len3; m++) {
        user = ref3[m];
        if (user.user.reference != null) {
          userList.push({
            basetype: "user",
            user: {
              _id: user.user._id,
              reference: user.user.reference
            }
          });
        }
      }
      baseData.user = userList;
      console.log("BaseMigration: Enhanced user data, only reference and id are kept for migration purposes.", baseData.user);
    }
    return this;
  };

  BaseMigration.prototype.loadBaseData = function() {
    var base_data, dfr, fn, i, len, promises, type, types;
    base_data = {
      dump_version: BaseMigration.dumpVersion
    };
    promises = [];
    types = ["tags", "transitions", "pool", "config", "objecttype", "group", "right", "user"];
    fn = (function(_this) {
      return function(type) {
        return promises.push(ez5.api[type]().done(function(data) {
          return base_data[type] = data;
        }));
      };
    })(this);
    for (i = 0, len = types.length; i < len; i++) {
      type = types[i];
      fn(type);
    }
    dfr = new CUI.Deferred();
    CUI.when(promises).done((function(_this) {
      return function() {
        _this.enhanceBaseData(base_data);
        _this.__baseData = base_data;
        return dfr.resolve();
      };
    })(this)).fail((function(_this) {
      return function() {
        return CUI.alert({
          text: $$("base.migration.error.load_base_data_failed")
        });
      };
    })(this));
    return dfr.promise();
  };

  BaseMigration.prototype["export"] = function() {
    var baseData, i, inst, k, len, name, ref;
    name = [];
    inst = ez5.session.getInstance();
    ref = ["name"];
    for (i = 0, len = ref.length; i < len; i++) {
      k = ref[i];
      name.push(inst[k]);
    }
    baseData = this.getBaseData();
    return CUI.downloadData(JSON.stringify(baseData), ez5.session.getEasydbName() + "_Permissions_" + CUI.util.moment().format('YYYY-MM-DD') + ".json");
  };

  BaseMigration.prototype.getSourceData = function() {
    return this.__sourceData;
  };

  BaseMigration.prototype.getConsole = function() {
    return new CUI.SimplePane({
      header_left: new CUI.Label({
        text: $$("base.migration.console.text")
      }),
      header_right: {
        icon: $$("base.migration.console.icon"),
        onClick: (function(_this) {
          return function() {
            return _this.__console.clear();
          };
        })(this)
      },
      content: this.__console
    });
  };

  BaseMigration.prototype.presentUploadedData = function(__sourceData) {
    var i, k, len, migrate_key, migrate_keys, mod, ref, ref1, source_nodes, source_tree, v;
    this.__sourceData = __sourceData;
    this.enhanceBaseData(this.__sourceData);
    source_nodes = [];
    migrate_keys = ["config", "group", "tags", "transitions", "objecttype", "pool", "dump_version", "_utf8_test", "preset"];
    ref = this.__sourceData;
    for (k in ref) {
      v = ref[k];
      if (!k.startsWith("_") && indexOf.call(migrate_keys, k) < 0) {
        this.log($$("base.migration.console.log.skipping-unsupported-data"), k, v.length, v);
      }
    }
    for (i = 0, len = migrate_keys.length; i < len; i++) {
      migrate_key = migrate_keys[i];
      ref1 = this.__sourceData;
      for (k in ref1) {
        v = ref1[k];
        if (k !== migrate_key) {
          continue;
        }
        switch (k) {
          case "pool":
            source_nodes.push.apply(source_nodes, BaseMigrationNodePool.getSourceNodesFromData(this, v));
            break;
          case "objecttype":
            source_nodes.push.apply(source_nodes, BaseMigrationNodeObjecttype.getSourceNodesFromData(this, v));
            break;
          case "tags":
            source_nodes.push.apply(source_nodes, BaseMigrationNodeTagGroup.getSourceNodesFromData(this, v));
            break;
          case "group":
            source_nodes.push.apply(source_nodes, BaseMigrationNodeGroup.getSourceNodesFromData(this, v));
            break;
          case "transitions":
            source_nodes.push.apply(source_nodes, BaseMigrationNodeTransition.getSourceNodesFromData(this, v));
            break;
          case "preset":
            source_nodes.push.apply(source_nodes, BaseMigrationNodePreset.getSourceNodesFromData(this, v));
            break;
          case "dump_version":
            console.info("Dump Version:", v);
            break;
          case "_utf8_test":
            console.info("Utf8-Test:", v);
        }
      }
    }
    source_tree = new CUI.ListViewTree({
      cols: ["maximize"],
      selectableRows: true,
      header_left: new CUI.Label({
        text: $$("base.migration.source-tree.header.text")
      }),
      onSelect: (function(_this) {
        return function(ev, info) {
          var actionPane;
          actionPane = info.node.getActionPane();
          return _this.__layout.replace(actionPane, "center");
        };
      })(this),
      onDeselect: (function(_this) {
        return function(ev, info) {
          return _this.__layout.replace(_this.getEmptyPane(), "center");
        };
      })(this),
      children: source_nodes
    });
    this.__layout = new CUI.HorizontalLayout({
      left: {
        "class": "ez5-base-migration-tree",
        content: source_tree.render(),
        flexHandle: {
          hidden: false,
          state_name: "base-migration-tree"
        }
      },
      center: {
        "class": "ez5-base-migration-content",
        content: this.getEmptyPane()
      },
      right: {
        "class": "ez5-base-migration-console",
        flexHandle: {
          hidden: false,
          state_name: "base-migration-console"
        },
        content: this.getConsole()
      }
    });
    mod = new CUI.Modal({
      "class": "ez5-base-migration-modal",
      cancel: true,
      fill_space: "both",
      onHide: (function(_this) {
        return function() {
          return delete _this.__baseData;
        };
      })(this),
      pane: {
        header_left: new CUI.Label({
          text: $$("base.migration.choice.title")
        }),
        content: this.__layout,
        footer_right: new LocaButton({
          loca_key: "base.migration.migration.button.done",
          secondary: true,
          onClick: (function(_this) {
            return function() {
              return mod.destroy();
            };
          })(this)
        })
      }
    }).show();
    return source_tree.root.open();
  };

  BaseMigration.prototype.getEmptyPane = function() {
    return new CUI.EmptyLabel({
      centered: true,
      multiline: true,
      markdown: true,
      text: $$("base.migration.empty-pane.text.md")
    });
  };

  BaseMigration.dumpVersion = 1;

  return BaseMigration;

})(RootMenuApp);

MigrateSkipException = (function(superClass) {
  extend(MigrateSkipException, superClass);

  function MigrateSkipException() {
    return MigrateSkipException.__super__.constructor.apply(this, arguments);
  }

  return MigrateSkipException;

})(UserError);

ez5.session_ready(function() {
  return ez5.rootMenu.registerApp(BaseMigration);
});
