text: import { M_State } from "@utkusarioglu/state";
  import { M_Namespace } from "@utkusarioglu/namespace";
  import { Parent } from "@utkusarioglu/mixer";
  import { Resolution } from "../Resolution/resolution";
  import { C_Resolver } from "../Common/c_resolver";
  import { e_typeDefinition, e_expressionType } from "../Common/t_resolver";
  const RI = "RI";
  export class Resolver extends Parent().with(M_State, M_Namespace) {
      constructor(channel) {
          super();
          this
              .set_GlobalNamespace(channel)
              .initialize_State({
              MinTrailDepth: 1,
              MaxTrailDepth: 100,
              Recursion: false,
          });
      }
      get_EntryPoint() {
          return this.get_State().get_Var("EntryPoint");
      }
      set_ExpressionTrail(expression_trail) {
          const resolution_instruction = [RI, expression_trail];
          this.set_Resolution(new Resolution(resolution_instruction));
          return this;
      }
      set_ExpressionStack(expression_stack) {
          const resolution_instruction = [
              RI,
              Resolution.produce_ExpressionTrail_FromStack(expression_stack)
          ];
          this.set_Resolution(new Resolution(resolution_instruction));
          return this;
      }
      set_ResolutionInstruction(resolution_instruction) {
          this.set_Resolution(new Resolution(resolution_instruction));
          return this;
      }
      set_Resolution(resolution) {
          this.set_Passage(resolution);
          return this;
      }
      set_Passage(passage) {
          this.get_State().set_Var("EntryPoint", passage);
          return this;
      }
      static disable_Passage(passage) {
          return C_Resolver.DISABLED_PHRASE + JSON.stringify(passage);
      }
      static enable_Passage(disabled_passage) {
          const phrase = C_Resolver.DISABLED_PHRASE;
          if (this.is_DisabledPassage(disabled_passage)) {
              return JSON.parse(disabled_passage.slice(phrase.length));
          }
          throw new Error(C_Resolver.E_NonStringType + "\n" + JSON.stringify(disabled_passage));
      }
      static is_DisabledPassage(passage_candidate) {
          const phrase = C_Resolver.DISABLED_PHRASE;
          return typeof passage_candidate === "string" &&
              passage_candidate.slice(0, phrase.length) === phrase;
      }
      set_Sources(sources) {
          this.get_State().set_Var("Sources", sources);
          return this;
      }
      get_Sources() {
          return this.get_State().get_Var("Sources");
      }
      set_MaxResolutionDepth(max_trail_depth) {
          this.get_State().set_Var("MaxTrailDepth", max_trail_depth);
          return this;
      }
      get_MaxResolutionDepth() {
          return this.get_State().get_Var("MaxTrailDepth");
      }
      set_MinResolutionDepth(min_trail_depth) {
          if (min_trail_depth < 1) {
              throw new Error(C_Resolver.E_MinTrailDepthLimit);
          }
          this.get_State().set_Var("MinTrailDepth", min_trail_depth);
          return this;
      }
      get_MinResolutionDepth() {
          return this.get_State().get_Var("MinTrailDepth");
      }
      check_ResolutionDepth(resolution) {
          const max_depth = this.get_MaxResolutionDepth();
          const min_depth = this.get_MinResolutionDepth();
          let error_message = [];
          if (min_depth > max_depth) {
              error_message.push(C_Resolver.E_DepthInconsistent);
          }
          if (Resolution.produce_ResolutionDepth(resolution) >= max_depth) {
              error_message.push(C_Resolver.E_TooDeep);
          }
          if (Resolution.produce_ResolutionDepth(resolution) < min_depth) {
              error_message.push(C_Resolver.E_TooShallow);
          }
          if (error_message.length !== 0) {
              throw new Error(error_message.join("\n") + JSON.stringify(resolution));
          }
      }
      set_Recursion(recursion_state) {
          this.get_State().set_Var("Recursion", recursion_state);
          return this;
      }
      get_Recursion() {
          return this.get_State().get_Var("Recursion");
      }
      produce_Resolute() {
          const entry_point = this.get_EntryPoint();
          const resolute = this.build_Items(entry_point);
          this.remove_State();
          return resolute;
      }
      build_Items(items) {
          switch (Resolver.check_ItemType(items)) {
              case e_typeDefinition.ResolutionInstruction:
                  items = new Resolution(items);
              case e_typeDefinition.Resolution:
                  return this.build_Resolution(items);
              case e_typeDefinition.Array:
                  return this.build_Array(items);
              case e_typeDefinition.Object:
                  return this.build_Object(items);
              default:
                  return items;
          }
      }
      build_Array(items) {
          const item_list = items.map((item) => {
              return this.build_Items(item);
          });
          return item_list;
      }
      build_Object(item) {
          let final = {};
          if (item.constructor.name !== "Object") {
              final = item;
          }
          else {
              Object.entries(item).forEach(([key, value]) => {
                  switch (Resolver.check_ItemType(value)) {
                      case e_typeDefinition.ResolutionInstruction:
                          const resolution = new Resolution(value);
                          final[key] = this.build_Resolution(resolution);
                          break;
                      case e_typeDefinition.Array:
                          final[key] = this.build_Array(value);
                          break;
                      case e_typeDefinition.Object:
                          final[key] = this.build_Object(value);
                          break;
                      default:
                          final[key] = value;
                  }
              });
          }
          return final;
      }
      build_Resolution(resolution) {
          this.check_ResolutionDepth(resolution);
          let base = this.get_Sources();
          const rules = this.retrieve_ResolutionRules(resolution);
          const execution_step_stack = resolution.produce_ExecutionStepStack(rules);
          execution_step_stack.forEach((execution_step) => {
              const expression = execution_step[1];
              const expression_type = execution_step[0];
              this.check_ExpressionAvailability(base, expression, execution_step_stack);
              if (expression_type === e_expressionType.Key) {
                  base = base[expression];
              }
              else {
                  const step_arguments = this.build_Arguments(execution_step[2]);
                  if (expression_type === e_expressionType.Instantiate) {
                      base = new base[expression](...step_arguments);
                  }
                  else {
                      base = base[expression](...step_arguments);
                  }
              }
          });
          const built_items = this.build_Items(base);
          return built_items;
      }
      check_ExpressionAvailability(base, expression, execution_step_stack) {
          if (base[expression] === undefined) {
              throw new Error(`${C_Resolver.DoesNotCarry.subs(expression)}\n${JSON.stringify(execution_step_stack)}`);
          }
      }
      build_Arguments(step_arguments) {
          if (step_arguments !== undefined) {
              return step_arguments.map(argument => {
                  switch (Resolver.check_ItemType(argument)) {
                      case e_typeDefinition.ResolutionInstruction:
                          const resolution = new Resolution(argument);
                          return this.build_Resolution(resolution);
                      case e_typeDefinition.Object:
                          return this.build_Object(argument);
                      case e_typeDefinition.Array:
                          return this.build_Array(argument);
                      default:
                          return argument;
                  }
              });
          }
          else {
              return [];
          }
      }
      static check_ItemType(item) {
          if (item === null) {
              return e_typeDefinition.Null;
          }
          else if (item === undefined) {
              return e_typeDefinition.Undefined;
          }
          else if (item instanceof Resolution) {
              return e_typeDefinition.Resolution;
          }
          else if (Resolution.is_ResolutionInstruction(item)) {
              return e_typeDefinition.ResolutionInstruction;
          }
          else if (Array.isArray(item)) {
              return e_typeDefinition.Array;
          }
          else if (item.is_Object()) {
              return e_typeDefinition.Object;
          }
          else {
              return e_typeDefinition.Other;
          }
      }
      static retrieve_ItemTypeArray(items) {
          const first_type = Resolver.check_ItemType(items[0]);
          const type_consistent = items.every((item) => {
              return first_type === Resolver.check_ItemType(item);
          });
          if (type_consistent) {
              return first_type;
          }
          else {
              return e_typeDefinition.VariableType;
          }
      }
      retrieve_ResolutionRules(resolution) {
          const sources = this.get_Sources();
          const first_expression = resolution.get_ExpressionStack()[0];
          const resolution_rules_method_name = C_Resolver.RulesVarName;
          return sources.sniff([
              Resolution.extract_MethodName(first_expression),
              resolution_rules_method_name
          ], () => {
              return {};
          }, (rules) => {
              return rules;
          });
      }
  }
  //# sourceMappingURL=resolver.js.map