"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.formatInputs = formatInputs;
exports.formatVars = formatVars;
exports.generateInputId = generateInputId;
exports.packagePolicyToSimplifiedPackagePolicy = packagePolicyToSimplifiedPackagePolicy;
exports.simplifiedPackagePolicytoNewPackagePolicy = simplifiedPackagePolicytoNewPackagePolicy;
var _constants = require("../constants");
var _errors = require("../errors");
var _ = require(".");
/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License
 * 2.0; you may not use this file except in compliance with the Elastic License
 * 2.0.
 */

function packagePolicyToSimplifiedPackagePolicy(packagePolicy) {
  const formattedPackagePolicy = packagePolicy;
  formattedPackagePolicy.inputs = formatInputs(packagePolicy.inputs);
  return formattedPackagePolicy;
}
function generateInputId(input) {
  return `${input.policy_template ? `${input.policy_template}-` : ''}${input.type}`;
}
function formatInputs(inputs) {
  return inputs.reduce((acc, input) => {
    const inputId = generateInputId(input);
    if (!acc) {
      acc = {};
    }
    acc[inputId] = {
      enabled: input.enabled,
      vars: formatVars(input.vars),
      streams: formatStreams(input.streams)
    };
    return acc;
  }, {});
}
function formatVars(vars) {
  if (!vars) {
    return;
  }
  return Object.entries(vars).reduce((acc, [varKey, varRecord]) => {
    var _varRecord$value;
    // the dataset var uses an internal format before we send it
    if (varKey === _constants.DATASET_VAR_NAME && varRecord !== null && varRecord !== void 0 && (_varRecord$value = varRecord.value) !== null && _varRecord$value !== void 0 && _varRecord$value.dataset) {
      acc[varKey] = varRecord === null || varRecord === void 0 ? void 0 : varRecord.value.dataset;
    } else {
      acc[varKey] = varRecord === null || varRecord === void 0 ? void 0 : varRecord.value;
    }
    return acc;
  }, {});
}
function formatStreams(streams) {
  return streams.reduce((acc, stream) => {
    if (!acc) {
      acc = {};
    }
    acc[stream.data_stream.dataset] = {
      enabled: stream.enabled,
      vars: formatVars(stream.vars)
    };
    return acc;
  }, {});
}
function assignVariables(userProvidedVars, varsRecord, ctxMessage = '') {
  Object.entries(userProvidedVars).forEach(([varKey, varValue]) => {
    if (!varsRecord || !varsRecord[varKey]) {
      throw new _errors.PackagePolicyValidationError(`Variable ${ctxMessage}:${varKey} not found`);
    }
    varsRecord[varKey].value = varValue;
  });
}
function simplifiedPackagePolicytoNewPackagePolicy(data, packageInfo, options) {
  const {
    policy_id: policyId,
    namespace,
    name,
    description,
    inputs = {},
    vars: packageLevelVars
  } = data;
  const packagePolicy = (0, _.packageToPackagePolicy)(packageInfo, policyId, namespace, name, description);
  if (packagePolicy.package && options !== null && options !== void 0 && options.experimental_data_stream_features) {
    packagePolicy.package.experimental_data_stream_features = options.experimental_data_stream_features;
  }

  // Build a input and streams Map to easily find package policy stream
  const inputMap = new Map();
  packagePolicy.inputs.forEach(input => {
    const streamMap = new Map();
    input.streams.forEach(stream => {
      streamMap.set(stream.data_stream.dataset, stream);
    });
    inputMap.set(generateInputId(input), {
      input,
      streams: streamMap
    });
  });
  if (packageLevelVars) {
    assignVariables(packageLevelVars, packagePolicy.vars);
  }
  Object.entries(inputs).forEach(([inputId, val]) => {
    var _inputMap$get;
    const {
      enabled,
      streams = {},
      vars: inputLevelVars
    } = val;
    const {
      input: packagePolicyInput,
      streams: streamsMap
    } = (_inputMap$get = inputMap.get(inputId)) !== null && _inputMap$get !== void 0 ? _inputMap$get : {};
    if (!packagePolicyInput || !streamsMap) {
      throw new _errors.PackagePolicyValidationError(`Input not found: ${inputId}`);
    }
    if (enabled === false) {
      packagePolicyInput.enabled = false;
    } else {
      packagePolicyInput.enabled = true;
    }
    if (inputLevelVars) {
      assignVariables(inputLevelVars, packagePolicyInput.vars, `${inputId}`);
    }
    Object.entries(streams).forEach(([streamId, streamVal]) => {
      const {
        enabled: streamEnabled,
        vars: streamsLevelVars
      } = streamVal;
      const packagePolicyStream = streamsMap.get(streamId);
      if (!packagePolicyStream) {
        throw new _errors.PackagePolicyValidationError(`Stream not found ${inputId}: ${streamId}`);
      }
      if (streamEnabled === false) {
        packagePolicyStream.enabled = false;
      } else {
        packagePolicyStream.enabled = true;
      }
      if (streamsLevelVars) {
        assignVariables(streamsLevelVars, packagePolicyStream.vars, `${inputId} ${streamId}`);
      }
    });
  });
  return packagePolicy;
}