'use strict';
var __createBinding =
  (this && this.__createBinding) ||
  (Object.create
    ? function (o, m, k, k2) {
        if (k2 === undefined) k2 = k;
        var desc = Object.getOwnPropertyDescriptor(m, k);
        if (
          !desc ||
          ('get' in desc ? !m.__esModule : desc.writable || desc.configurable)
        ) {
          desc = {
            enumerable: true,
            get: function () {
              return m[k];
            },
          };
        }
        Object.defineProperty(o, k2, desc);
      }
    : function (o, m, k, k2) {
        if (k2 === undefined) k2 = k;
        o[k2] = m[k];
      });
var __setModuleDefault =
  (this && this.__setModuleDefault) ||
  (Object.create
    ? function (o, v) {
        Object.defineProperty(o, 'default', { enumerable: true, value: v });
      }
    : function (o, v) {
        o['default'] = v;
      });
var __importStar =
  (this && this.__importStar) ||
  function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null)
      for (var k in mod)
        if (k !== 'default' && Object.prototype.hasOwnProperty.call(mod, k))
          __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
  };
var __importDefault =
  (this && this.__importDefault) ||
  function (mod) {
    return mod && mod.__esModule ? mod : { default: mod };
  };
Object.defineProperty(exports, '__esModule', { value: true });
exports.getDeviceConfig =
  exports.setRoot =
  exports.on =
  exports.getConfig =
  exports.isOpened =
  exports.close =
  exports.open =
  exports.init =
    void 0;
const fs = __importStar(require('fs'));
const path = __importStar(require('path'));
const utils_1 = require('./utils/utils');
const addCamerasInConfig_1 = __importDefault(require('./utils/addCamerasInConfig'));
const styleNames_1 = __importDefault(require('./utils/styleNames'));
const createConfigPage_1 = __importDefault(
  require('./utils/recursions/createConfigPage/createConfigPage'),
);
const syncConfig_1 = __importDefault(require('./utils/recursions/syncConfig/syncConfig'));
const parseConfig_1 = __importDefault(
  require('./utils/recursions/parseConfig/parseConfig'),
);
const checkConfig_1 = __importDefault(
  require('./utils/recursions/checkConfig/checkConfig'),
);
const config = {};
let isConfigOpened = false;
let isConfigChanged = false;
let isInitialized = false;
const paths = {
  local: '',
  device: '',
  default: '',
  remoteUrl: '',
};
const newFields = []; // Если включена загрузка удалённого конфига, то при синхронизации конфигов здесь будут храниться новые поля
// инициализация модуля
const init = ({ appName, localConfigPath, deviceConfigPath, defaultConfigPath }) => {
  if (isInitialized) {
    (0, utils_1.emit)('error', 'конфиг уже инициализирован');
    return;
  }
  // создаём абсолютные пути и читаем конфиги
  paths.device = path.resolve(
    path.join(deviceConfigPath, `${appName}-device-config.json`),
  );
  paths.local = path.resolve(path.join(localConfigPath, `${appName}-app-config.json`));
  paths.default = path.resolve(
    path.join(defaultConfigPath, `${appName}-config-default.json`),
  );
  readDefaultConfig();
  readLocalConfig();
  readDeviceConfig();
  if (!config.default && !config.local) {
    throw new Error(
      'Невозможно построить конфиг, так как отсутстувуют локальный и дефолтный конфиги',
    );
  }
  if (!config.local) {
    isConfigChanged = true;
  }
  // читаем удалённый конфиг
  (0, utils_1.readRemoteConfig)(config, paths.remoteUrl).then(async (remoteConfig) => {
    config.remote = remoteConfig;
    // объединяем все конфиги, которые есть в наличии
    config.united = (0, syncConfig_1.default)(
      (0, utils_1.cloneObject)(config.remote || {}),
      (0, utils_1.cloneObject)(config.local || {}),
      (0, utils_1.cloneObject)(config.default || {}),
      newFields,
    );
    if (newFields.length > 0) {
      isConfigChanged = true;
    }
    checkFieldForCameras();
    // добавляем камеры
    const cameras = await (0, addCamerasInConfig_1.default)(config);
    if (
      JSON.stringify(config.united.devices.value.camera.value) !== JSON.stringify(cameras)
    ) {
      config.united.devices.value.camera.value = cameras;
      isConfigChanged = true;
    }
    // сохраняем конфиги, если есть изменения
    if ((0, checkConfig_1.default)(config.united) || isConfigChanged) {
      fs.writeFileSync(paths.local, JSON.stringify(config.united, null, '\t'));
      isConfigChanged = false;
    }
    if (config.default && (0, checkConfig_1.default)(config.default)) {
      fs.writeFileSync(paths.default, JSON.stringify(config.default, null, '\t'));
    }
    config.parsed = (0, parseConfig_1.default)(config.united);
    (0, utils_1.readyEmit)(config.parsed);
    isInitialized = true;
  });
};
exports.init = init;
const checkFieldForCameras = () => {
  var _a, _b, _c, _d;
  if (
    !((_d =
      (_c =
        (_b = (_a = config.united) === null || _a === void 0 ? void 0 : _a.devices) ===
          null || _b === void 0
          ? void 0
          : _b.value) === null || _c === void 0
        ? void 0
        : _c.camera) === null || _d === void 0
      ? void 0
      : _d.value)
  ) {
    config.united.devices = config.united.devices || {
      name: 'Периферийные устройства',
      key: 'devices',
    };
    config.united.devices.value = config.united.devices.value || {};
    config.united.devices.value.camera = config.united.devices.value.camera || {
      name: 'Камера',
      key: 'camera',
    };
    isConfigChanged = true;
  }
};
const readDefaultConfig = () => {
  config.default = (0, utils_1.readConfig)(
    paths.default,
    () => (0, utils_1.emit)('info', 'конфиг по умолчанию конфиг прочитан'),
    () => (0, utils_1.emit)('error', 'конфиг по умолчанию не найден'),
    () => (0, utils_1.emit)('error', 'не удалось прочитать конфиг по умолчанию'),
    () => (0, utils_1.emit)('warn', 'файл с дефолтным конфигом пуст'),
  );
};
const readLocalConfig = () => {
  config.local = (0, utils_1.readConfig)(
    paths.local,
    () => (0, utils_1.emit)('info', 'локальный конфиг прочитан'),
    () => (0, utils_1.emit)('warn', 'локальный конфиг не найден'),
    () => (0, utils_1.emit)('error', 'не удалось прочитать локальный конфиг'),
    () =>
      (0, utils_1.emit)(
        'warn',
        'файл с локальным конфигом пуст. Ему будет присвоен пустой объект',
      ),
  );
};
const readDeviceConfig = () => {
  const deviceConfig = (0, utils_1.readConfig)(
    paths.device,
    () => (0, utils_1.emit)('info', 'конфиг устройства прочитан'),
    () => (0, utils_1.emit)('error', 'конфиг устройства не найден'),
    () => (0, utils_1.emit)('error', 'не удалось прочитать конфиг устройства'),
    () => (0, utils_1.emit)('warn', 'файл с дефолтным устройства конфигом пуст'),
  );
  if (deviceConfig) {
    paths.remoteUrl = deviceConfig.remote_href;
    config.device = deviceConfig.device;
  }
};
const toggleDevMode = (e) => {
  var _a;
  if (e.ctrlKey && e.shiftKey && e.code === 'KeyX' && isConfigOpened) {
    // удаляем форму создания нового поля, если она есть
    if (config.HTML.classList.contains(styleNames_1.default.devMode)) {
      (_a = config.HTML.querySelector(`.${styleNames_1.default.form}`)) === null ||
      _a === void 0
        ? void 0
        : _a.remove();
    }
    config.HTML.classList.toggle(styleNames_1.default.devMode);
  }
};
const open = async (root) => {
  if (!isConfigOpened) {
    if (root) {
      config.root = root;
    }
    if (config.root) {
      // перепроверяем камеры, обновляем экспортный конфиг и строим HTML страницу
      checkFieldForCameras();
      config.united.devices.value.camera.value = await (0, addCamerasInConfig_1.default)(
        config,
      );
      config.parsed = (0, parseConfig_1.default)(config.united);
      config.HTML = await (0, createConfigPage_1.default)({
        config: config,
        newFields,
        isConfigChanged,
        pathToSaveLocalConfig: paths.local,
        pathToSaveDefaultConfig: paths.default,
      });
      try {
        config.root.appendChild(config.HTML);
        (0, utils_1.emit)('open', 'конфиг открыт');
        isConfigOpened = true;
        document.addEventListener('keydown', toggleDevMode);
      } catch (err) {
        console.error(err);
        (0, utils_1.emit)(
          'error',
          'произошла ошибка при попытке открыть страницу конфига',
        );
      }
    } else {
      (0, utils_1.emit)('error', 'родительский элемент не задан');
    }
  }
};
exports.open = open;
const close = () => {
  if (isConfigOpened) {
    try {
      config.root.removeChild(config.HTML);
      (0, utils_1.emit)('close', 'конфиг закрыт');
      isConfigOpened = false;
      document.removeEventListener('keydown', toggleDevMode);
    } catch (err) {
      console.error(err);
      (0, utils_1.emit)('error', 'произошла ошибка при попытке закрыть конфиг');
    }
  }
};
exports.close = close;
const isOpened = () => isConfigOpened;
exports.isOpened = isOpened;
const getConfig = () => config.parsed;
exports.getConfig = getConfig;
const getDeviceConfig = () =>
  config.device ? (0, utils_1.cloneObject)(config.device) : null;
exports.getDeviceConfig = getDeviceConfig;
const setRoot = (root) => {
  config.root = root;
};
exports.setRoot = setRoot;
const on = (event, action) => {
  utils_1.emitter.on(event, (message, config) => action(message, config));
};
exports.on = on;
//# sourceMappingURL=index.js.map
