'use strict';

var object = require('./object-68e154cb.js');
require('json-stringify-deterministic');
require('immer');
require('crypto');
require('fs');
require('https');
require('path');

const createEmptyScopeFrameworkState = () => ({
  "rootPath": "A",
  "elements": [
    {
      "id": "uGcJFhnNtFSCaVRjaELUqBsMgUI=",
      "name": "Scope Name",
      "version": 1,
      "type": "Scope",
      "path": "A.1",
      "components": {
        "content": "Scope description goes here."
      }
    }
  ]
});
const dateTimeNow = (/* @__PURE__ */ new Date()).toISOString();
const createEmptyExtendedScopeFrameworkState = () => ({
  name: "",
  created: dateTimeNow,
  lastModified: dateTimeNow,
  documentType: "makerdao/scope-framework",
  revision: 0,
  state: createEmptyScopeFrameworkState(),
  attachments: {}
});
const loadScopeFrameworkFromFile = async (path) => {
  return object.loadFromFile(
    path,
    reducer
  );
};
const loadScopeFrameworkFromInput = async (input) => {
  return object.loadFromInput(
    input,
    reducer
  );
};
const saveScopeFrameworkToFile = (document, path, name) => {
  return object.saveToFile(document, path, "mdsf", name);
};
const saveScopeFrameworkToFileHandle = async (document, input) => {
  return object.saveToFileHandle(document, input);
};

// node_modules/@acaldas/document-model-graphql/dist/scope-framework.js
var l = (n) => n != null;
var h = object.z.any().refine((n) => l(n));
function a() {
  return object.z.object({
    __typename: object.z.literal("AddElementInput").optional(),
    components: t().nullable(),
    id: object.z.string(),
    name: object.z.string().nullable(),
    path: object.z.string(),
    type: o
  });
}
function r() {
  return object.z.object({
    __typename: object.z.literal("ArticleComponent").optional(),
    content: object.z.string().nullable()
  });
}
function i() {
  return object.z.object({
    __typename: object.z.literal("CoreComponent").optional(),
    content: object.z.string().nullable()
  });
}
function t() {
  return object.z.union([r(), i(), u(), S(), b()]);
}
function p() {
  return object.z.object({
    __typename: object.z.literal("MoveElementInput").optional(),
    id: object.z.string(),
    newParentId: object.z.string()
  });
}
function m() {
  return object.z.object({
    __typename: object.z.literal("RemoveElementInput").optional(),
    id: object.z.string()
  });
}
function c() {
  return object.z.object({
    __typename: object.z.literal("ReorderElementsInput").optional(),
    order: object.z.array(object.z.string()),
    parentElementId: object.z.string()
  });
}
function u() {
  return object.z.object({
    __typename: object.z.literal("ScopeComponent").optional(),
    content: object.z.string().nullable()
  });
}
function s() {
  return object.z.object({
    __typename: object.z.literal("ScopeFrameworkElement").optional(),
    components: t().nullable(),
    id: object.z.string(),
    name: object.z.string().nullable(),
    path: object.z.string(),
    type: o.nullable(),
    version: object.z.number()
  });
}
var o = object.z.enum(["Article", "Core", "Scope", "Section", "TypeSpecification"]);
function I() {
  return object.z.union([a(), p(), m(), c(), y(), d(), g(), f()]);
}
function E() {
  return object.z.object({
    __typename: object.z.literal("ScopeFrameworkState").optional(),
    elements: object.z.array(s()),
    rootPath: object.z.string()
  });
}
function S() {
  return object.z.object({
    __typename: object.z.literal("SectionComponent").optional(),
    content: object.z.string().nullable()
  });
}
function y() {
  return object.z.object({
    __typename: object.z.literal("SetRootPathInput").optional(),
    newRootPath: object.z.string()
  });
}
function b() {
  return object.z.object({
    __typename: object.z.literal("TypeSpecificationComponent").optional(),
    additionalLogic: object.z.string().nullable(),
    category: _.nullable(),
    documentIdentifierRules: object.z.string().nullable(),
    name: object.z.string().nullable(),
    overview: object.z.string().nullable(),
    typeAuthority: object.z.string().nullable()
  });
}
var _ = object.z.enum(["Accessory", "Immutable", "Primary", "Supporting"]);
function d() {
  return object.z.object({
    __typename: object.z.literal("UpdateElementComponentsInput").optional(),
    components: t().nullable(),
    id: object.z.string()
  });
}
function g() {
  return object.z.object({
    __typename: object.z.literal("UpdateElementNameInput").optional(),
    id: object.z.string(),
    name: object.z.string().nullable()
  });
}
function f() {
  return object.z.object({
    __typename: object.z.literal("UpdateElementTypeInput").optional(),
    id: object.z.string(),
    type: o
  });
}
var j = Object.freeze(Object.defineProperty({
  __proto__: null,
  AddElementInputSchema: a,
  ArticleComponentSchema: r,
  CoreComponentSchema: i,
  ElementComponentsSchema: t,
  MoveElementInputSchema: p,
  RemoveElementInputSchema: m,
  ReorderElementsInputSchema: c,
  ScopeComponentSchema: u,
  ScopeFrameworkElementSchema: s,
  ScopeFrameworkElementTypeSchema: o,
  ScopeFrameworkInputSchema: I,
  ScopeFrameworkStateSchema: E,
  SectionComponentSchema: S,
  SetRootPathInputSchema: y,
  TypeSpecificationComponentCategorySchema: _,
  TypeSpecificationComponentSchema: b,
  UpdateElementComponentsInputSchema: d,
  UpdateElementNameInputSchema: g,
  UpdateElementTypeInputSchema: f,
  definedNonNullAnySchema: h,
  isDefinedNonNullAny: l
}, Symbol.toStringTag, { value: "Module" }));

const rootSegment = (path) => {
  return path.split(".", 2)[0];
};
const precedes = (pathA, pathB) => {
  const segmentsA = pathA.split("."), segmentsB = pathB.split("."), commonLength = Math.min(segmentsA.length, segmentsB.length);
  if (segmentsA[0] != segmentsB[0]) {
    return segmentsA[0] < segmentsB[0];
  }
  for (let i = 1; i < commonLength; i++) {
    if (segmentsA[i] != segmentsB[i]) {
      return parseInt(segmentsA[i]) < parseInt(segmentsB[i]);
    }
  }
  return segmentsA.length < segmentsB.length;
};
const reducer$1 = {
  setRootPathOperation(state, action) {
    const rootPathPattern = /^[A-Z]+$/;
    if (!action.input.newRootPath.match(rootPathPattern)) {
      throw new Error(
        `Invalid root path format ${action.input.newRootPath}. Use one or more capital letters: 'A', 'D', 'AQ', ...`
      );
    }
    const findString = state.rootPath + ".", newString = action.input.newRootPath + ".";
    state.rootPath = action.input.newRootPath;
    state.elements = state.elements.map((e) => ({
      ...e,
      path: e.path.replace(findString, newString)
    }));
  },
  addElementOperation(state, action) {
    const result = [];
    const newElement = {
      id: action.input.id,
      version: 1,
      path: action.input.path,
      type: action.input.type,
      name: action.input.name,
      components: action.input.components
    };
    if (rootSegment(newElement.path) != state.rootPath) {
      throw new Error(
        `Cannot add element with root segment ${rootSegment(
          newElement.path
        )} to document with root path ${state.rootPath}`
      );
    }
    let inserted = false, nextElement = null;
    while (nextElement = state.elements.shift()) {
      if (!inserted && precedes(newElement.path, nextElement.path)) {
        result.push(newElement);
        inserted = true;
      }
      if (!inserted && newElement.path == nextElement.path) {
        throw new Error(
          `New element's path ${newElement.path} already exists.`
        );
      }
      result.push(nextElement);
    }
    if (!inserted) {
      result.push(newElement);
    }
    state.elements = result;
  },
  updateElementTypeOperation(state, action) {
    state.elements.filter((e) => e.id == action.input.id).forEach((e) => {
      e.type = action.input.type;
    });
  },
  updateElementNameOperation(state, action) {
    state.elements.filter((e) => e.id == action.input.id).forEach((e) => {
      e.name = action.input.name;
    });
  },
  updateElementComponentsOperation(state, action) {
    state.elements.filter((e) => e.id == action.input.id).forEach((e) => {
      e.components = action.input.components;
    });
  },
  removeElementOperation(state, action) {
    const element = state.elements.filter((e) => e.id == action.input.id)[0];
    if (element) {
      state.elements = state.elements.filter(
        (e) => !e.path.startsWith(element.path)
      );
    }
  },
  reorderElementsOperation(state, action) {
    throw new Error(
      'Reducer "reorderElementsOperation" not yet implemented'
    );
  },
  moveElementOperation(state, action) {
    throw new Error('Reducer "moveElementOperation" not yet implemented');
  }
};

const stateReducer = (state, action) => {
  if (object.isBaseAction(action)) {
    return state;
  }
  switch (action.type) {
    case "SET_ROOT_PATH":
      j.SetRootPathInputSchema().parse(action.input);
      reducer$1.setRootPathOperation(state, action);
      break;
    case "ADD_ELEMENT":
      j.AddElementInputSchema().parse(action.input);
      reducer$1.addElementOperation(state, action);
      break;
    case "UPDATE_ELEMENT_TYPE":
      j.UpdateElementTypeInputSchema().parse(action.input);
      reducer$1.updateElementTypeOperation(state, action);
      break;
    case "UPDATE_ELEMENT_NAME":
      j.UpdateElementNameInputSchema().parse(action.input);
      reducer$1.updateElementNameOperation(state, action);
      break;
    case "UPDATE_ELEMENT_COMPONENTS":
      j.UpdateElementComponentsInputSchema().parse(action.input);
      reducer$1.updateElementComponentsOperation(state, action);
      break;
    case "REMOVE_ELEMENT":
      j.RemoveElementInputSchema().parse(action.input);
      reducer$1.removeElementOperation(state, action);
      break;
    case "REORDER_ELEMENTS":
      j.ReorderElementsInputSchema().parse(action.input);
      reducer$1.reorderElementsOperation(state, action);
      break;
    case "MOVE_ELEMENT":
      j.MoveElementInputSchema().parse(action.input);
      reducer$1.moveElementOperation(state, action);
      break;
    default:
      return state;
  }
};
const reducer = object.createReducer(stateReducer);

const setRootPath = (input) => object.createAction(
  "SET_ROOT_PATH",
  { ...input }
);
const addElement = (input) => object.createAction(
  "ADD_ELEMENT",
  { ...input }
);
const updateElementType = (input) => object.createAction(
  "UPDATE_ELEMENT_TYPE",
  { ...input }
);
const updateElementName = (input) => object.createAction(
  "UPDATE_ELEMENT_NAME",
  { ...input }
);
const updateElementComponents = (input) => object.createAction(
  "UPDATE_ELEMENT_COMPONENTS",
  { ...input }
);
const removeElement = (input) => object.createAction(
  "REMOVE_ELEMENT",
  { ...input }
);
const reorderElements = (input) => object.createAction(
  "REORDER_ELEMENTS",
  { ...input }
);
const moveElement = (input) => object.createAction(
  "MOVE_ELEMENT",
  { ...input }
);

class ScopeFramework_Main extends object.BaseDocument {
  setRootPath(input) {
    return this.dispatch(setRootPath(input));
  }
  addElement(input) {
    return this.dispatch(addElement(input));
  }
  updateElementType(input) {
    return this.dispatch(updateElementType(input));
  }
  updateElementName(input) {
    return this.dispatch(updateElementName(input));
  }
  updateElementComponents(input) {
    return this.dispatch(updateElementComponents(input));
  }
  removeElement(input) {
    return this.dispatch(removeElement(input));
  }
  reorderElements(input) {
    return this.dispatch(reorderElements(input));
  }
  moveElement(input) {
    return this.dispatch(moveElement(input));
  }
}

let ScopeFramework$2 = class ScopeFramework extends object.BaseDocument {
  static fileExtension = "mdsf";
  constructor(initialState) {
    super(reducer, initialState || createEmptyExtendedScopeFrameworkState());
  }
  saveToFile(path, name) {
    return super.saveToFile(path, ScopeFramework.fileExtension, name);
  }
  loadFromFile(path) {
    return super.loadFromFile(path);
  }
  static async fromFile(path) {
    const document = new this();
    await document.loadFromFile(path);
    return document;
  }
};
object.applyMixins(ScopeFramework$2, [
  ScopeFramework_Main
]);

var gen = /*#__PURE__*/Object.freeze({
    __proto__: null,
    ScopeFramework: ScopeFramework$2,
    addElement: addElement,
    moveElement: moveElement,
    removeElement: removeElement,
    reorderElements: reorderElements,
    setRootPath: setRootPath,
    updateElementComponents: updateElementComponents,
    updateElementName: updateElementName,
    updateElementType: updateElementType
});

const { ScopeFramework, ...ScopeFrameworkActions } = gen;
const actions = { ...object.BaseActions, ...ScopeFrameworkActions };

var ScopeFramework$1 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    ScopeFramework: ScopeFramework,
    actions: actions,
    createEmptyExtendedScopeFrameworkState: createEmptyExtendedScopeFrameworkState,
    createEmptyScopeFrameworkState: createEmptyScopeFrameworkState,
    loadScopeFrameworkFromFile: loadScopeFrameworkFromFile,
    loadScopeFrameworkFromInput: loadScopeFrameworkFromInput,
    reducer: reducer,
    saveScopeFrameworkToFile: saveScopeFrameworkToFile,
    saveScopeFrameworkToFileHandle: saveScopeFrameworkToFileHandle
});

exports.ScopeFramework = ScopeFramework$1;
exports.ScopeFramework$1 = ScopeFramework;
exports.actions = actions;
exports.createEmptyExtendedScopeFrameworkState = createEmptyExtendedScopeFrameworkState;
exports.createEmptyScopeFrameworkState = createEmptyScopeFrameworkState;
exports.loadScopeFrameworkFromFile = loadScopeFrameworkFromFile;
exports.loadScopeFrameworkFromInput = loadScopeFrameworkFromInput;
exports.reducer = reducer;
exports.saveScopeFrameworkToFile = saveScopeFrameworkToFile;
exports.saveScopeFrameworkToFileHandle = saveScopeFrameworkToFileHandle;
//# sourceMappingURL=index-e6c47ede.js.map
