"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useOnSubmit = useOnSubmit;
var _react = require("react");
var _i18n = require("@kbn/i18n");
var _jsYaml = require("js-yaml");
var _get_azure_arm_props_from_package_policy = require("../../../../../../../services/get_azure_arm_props_from_package_policy");
var _hooks = require("../../../../../hooks");
var _services = require("../../../../../services");
var _common = require("../../../../../../../../common");
var _services2 = require("../../../../../../../../common/services");
var _hooks2 = require("../../../../../../integrations/hooks");
var _services3 = require("../../services");
var _components = require("../../components");
var _hooks3 = require("../../hooks");
var _prepare_input_pkg_policy_dataset = require("../../services/prepare_input_pkg_policy_dataset");
/*
 * 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.
 */

async function createAgentPolicy({
  packagePolicy,
  newAgentPolicy,
  withSysMonitoring
}) {
  var _packagePolicy$packag;
  // do not create agent policy with system integration if package policy already is for system package
  const packagePolicyIsSystem = (packagePolicy === null || packagePolicy === void 0 ? void 0 : (_packagePolicy$packag = packagePolicy.package) === null || _packagePolicy$packag === void 0 ? void 0 : _packagePolicy$packag.name) === _common.FLEET_SYSTEM_PACKAGE;
  const resp = await (0, _hooks.sendCreateAgentPolicy)(newAgentPolicy, {
    withSysMonitoring: withSysMonitoring && !packagePolicyIsSystem
  });
  if (resp.error) {
    throw resp.error;
  }
  if (!resp.data) {
    throw new Error('Invalid agent policy creation no data');
  }
  return resp.data.item;
}
async function savePackagePolicy(pkgPolicy) {
  const {
    policy,
    forceCreateNeeded
  } = await (0, _prepare_input_pkg_policy_dataset.prepareInputPackagePolicyDataset)(pkgPolicy);
  const result = await (0, _hooks.sendCreatePackagePolicy)({
    ...policy,
    ...(forceCreateNeeded && {
      force: true
    })
  });
  return result;
}
const DEFAULT_PACKAGE_POLICY = {
  name: '',
  description: '',
  namespace: 'default',
  policy_id: '',
  enabled: true,
  inputs: []
};
function useOnSubmit({
  agentCount,
  selectedPolicyTab,
  newAgentPolicy,
  withSysMonitoring,
  queryParamsPolicyId,
  packageInfo,
  integrationToEnable
}) {
  const {
    notifications
  } = (0, _hooks.useStartServices)();
  const confirmForceInstall = (0, _hooks2.useConfirmForceInstall)();
  // only used to store the resulting package policy once saved
  const [savedPackagePolicy, setSavedPackagePolicy] = (0, _react.useState)();
  // Form state
  const [formState, setFormState] = (0, _react.useState)('VALID');

  // Used to render extension components only when package policy is initialized
  const [isInitialized, setIsInitialized] = (0, _react.useState)(false);
  // Used to initialize the package policy once
  const isInitializedRef = (0, _react.useRef)(false);
  const [agentPolicy, setAgentPolicy] = (0, _react.useState)();
  // New package policy state
  const [packagePolicy, setPackagePolicy] = (0, _react.useState)({
    ...DEFAULT_PACKAGE_POLICY
  });

  // Validation state
  const [validationResults, setValidationResults] = (0, _react.useState)();
  const [hasAgentPolicyError, setHasAgentPolicyError] = (0, _react.useState)(false);
  const hasErrors = validationResults ? (0, _services3.validationHasErrors)(validationResults) : false;

  // Update agent policy method
  const updateAgentPolicy = (0, _react.useCallback)(updatedAgentPolicy => {
    if (updatedAgentPolicy) {
      setAgentPolicy(updatedAgentPolicy);
      if (packageInfo) {
        setHasAgentPolicyError(false);
      }
    } else {
      setHasAgentPolicyError(true);
      setAgentPolicy(undefined);
    }

    // eslint-disable-next-line no-console
    console.debug('Agent policy updated', updatedAgentPolicy);
  }, [packageInfo, setAgentPolicy]);
  // Update package policy validation
  const updatePackagePolicyValidation = (0, _react.useCallback)(newPackagePolicy => {
    if (packageInfo) {
      const newValidationResult = (0, _services3.validatePackagePolicy)(newPackagePolicy || packagePolicy, packageInfo, _jsYaml.safeLoad);
      setValidationResults(newValidationResult);
      // eslint-disable-next-line no-console
      console.debug('Package policy validation results', newValidationResult);
      return newValidationResult;
    }
  }, [packagePolicy, packageInfo]);
  // Update package policy method
  const updatePackagePolicy = (0, _react.useCallback)(updatedFields => {
    const newPackagePolicy = {
      ...packagePolicy,
      ...updatedFields
    };
    setPackagePolicy(newPackagePolicy);

    // eslint-disable-next-line no-console
    console.debug('Package policy updated', newPackagePolicy);
    const newValidationResults = updatePackagePolicyValidation(newPackagePolicy);
    const hasPackage = newPackagePolicy.package;
    const hasValidationErrors = newValidationResults ? (0, _services3.validationHasErrors)(newValidationResults) : false;
    const hasAgentPolicy = newPackagePolicy.policy_id && newPackagePolicy.policy_id !== '';
    if (hasPackage && (hasAgentPolicy || selectedPolicyTab === _components.SelectedPolicyTab.NEW) && !hasValidationErrors) {
      setFormState('VALID');
    } else {
      setFormState('INVALID');
    }
  }, [packagePolicy, setFormState, updatePackagePolicyValidation, selectedPolicyTab]);

  // Initial loading of package info
  (0, _react.useEffect)(() => {
    async function init() {
      if (isInitializedRef.current || !packageInfo) {
        return;
      }

      // Fetch all packagePolicies having the package name
      const {
        data: packagePolicyData
      } = await (0, _hooks.sendGetPackagePolicies)({
        perPage: _common.SO_SEARCH_LIMIT,
        page: 1,
        kuery: `${_common.PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${packageInfo.name}`
      });
      const incrementedName = (0, _services2.getMaxPackageName)(packageInfo.name, packagePolicyData === null || packagePolicyData === void 0 ? void 0 : packagePolicyData.items);
      isInitializedRef.current = true;
      updatePackagePolicy((0, _services.packageToPackagePolicy)(packageInfo, (agentPolicy === null || agentPolicy === void 0 ? void 0 : agentPolicy.id) || '', (agentPolicy === null || agentPolicy === void 0 ? void 0 : agentPolicy.namespace) || DEFAULT_PACKAGE_POLICY.namespace, DEFAULT_PACKAGE_POLICY.name || incrementedName, DEFAULT_PACKAGE_POLICY.description, integrationToEnable));
      setIsInitialized(true);
    }
    init();
  }, [packageInfo, agentPolicy, updatePackagePolicy, integrationToEnable, isInitialized]);
  (0, _react.useEffect)(() => {
    if (agentPolicy && packagePolicy.policy_id !== agentPolicy.id) {
      updatePackagePolicy({
        policy_id: agentPolicy.id,
        namespace: agentPolicy.namespace
      });
    }
  }, [packagePolicy, agentPolicy, updatePackagePolicy]);
  const onSaveNavigate = (0, _hooks3.useOnSaveNavigate)({
    packagePolicy,
    queryParamsPolicyId
  });
  const navigateAddAgent = policy => onSaveNavigate(policy, ['openEnrollmentFlyout']);
  const navigateAddAgentHelp = policy => onSaveNavigate(policy, ['showAddAgentHelp']);
  const onSubmit = (0, _react.useCallback)(async ({
    force,
    overrideCreatedAgentPolicy
  } = {}) => {
    var _createdPolicy$id, _createdPolicy;
    if (formState === 'VALID' && hasErrors) {
      setFormState('INVALID');
      return;
    }
    if (agentCount !== 0 && formState !== 'CONFIRM') {
      setFormState('CONFIRM');
      return;
    }
    let createdPolicy = overrideCreatedAgentPolicy;
    if (selectedPolicyTab === _components.SelectedPolicyTab.NEW && !overrideCreatedAgentPolicy) {
      try {
        var _ref, _newAgentPolicy$monit;
        setFormState('LOADING');
        if ((_ref = withSysMonitoring || ((_newAgentPolicy$monit = newAgentPolicy.monitoring_enabled) === null || _newAgentPolicy$monit === void 0 ? void 0 : _newAgentPolicy$monit.length)) !== null && _ref !== void 0 ? _ref : 0 > 0) {
          var _newAgentPolicy$monit2, _newAgentPolicy$monit3;
          const packagesToPreinstall = [];
          if (packageInfo) {
            packagesToPreinstall.push({
              name: packageInfo.name,
              version: packageInfo.version
            });
          }
          if (withSysMonitoring) {
            packagesToPreinstall.push(_common.FLEET_SYSTEM_PACKAGE);
          }
          if ((_newAgentPolicy$monit2 = (_newAgentPolicy$monit3 = newAgentPolicy.monitoring_enabled) === null || _newAgentPolicy$monit3 === void 0 ? void 0 : _newAgentPolicy$monit3.length) !== null && _newAgentPolicy$monit2 !== void 0 ? _newAgentPolicy$monit2 : 0 > 0) {
            packagesToPreinstall.push(_common.FLEET_ELASTIC_AGENT_PACKAGE);
          }
          if (packagesToPreinstall.length > 0) {
            await (0, _hooks.sendBulkInstallPackages)([...new Set(packagesToPreinstall)]);
          }
        }
        createdPolicy = await createAgentPolicy({
          newAgentPolicy,
          packagePolicy,
          withSysMonitoring
        });
        setAgentPolicy(createdPolicy);
        updatePackagePolicy({
          policy_id: createdPolicy.id
        });
      } catch (e) {
        setFormState('VALID');
        notifications.toasts.addError(e, {
          title: _i18n.i18n.translate('xpack.fleet.createAgentPolicy.errorNotificationTitle', {
            defaultMessage: 'Unable to create agent policy'
          })
        });
        return;
      }
    }
    setFormState('LOADING');
    // passing pkgPolicy with policy_id here as setPackagePolicy doesn't propagate immediately
    const {
      error,
      data
    } = await savePackagePolicy({
      ...packagePolicy,
      policy_id: (_createdPolicy$id = (_createdPolicy = createdPolicy) === null || _createdPolicy === void 0 ? void 0 : _createdPolicy.id) !== null && _createdPolicy$id !== void 0 ? _createdPolicy$id : packagePolicy.policy_id,
      force
    });
    const hasAzureArmTemplate = data !== null && data !== void 0 && data.item ? (0, _get_azure_arm_props_from_package_policy.getAzureArmPropsFromPackagePolicy)(data.item).templateUrl : false;
    const hasCloudFormation = data !== null && data !== void 0 && data.item ? (0, _services.getCloudFormationPropsFromPackagePolicy)(data.item).templateUrl : false;
    const hasGoogleCloudShell = data !== null && data !== void 0 && data.item ? (0, _services.getCloudShellUrlFromPackagePolicy)(data.item) : false;
    if (hasAzureArmTemplate) {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_AZURE_ARM_TEMPLATE');
    } else {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_NO_AGENTS');
    }
    if (hasCloudFormation) {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_CLOUD_FORMATION');
    } else {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_NO_AGENTS');
    }
    if (hasGoogleCloudShell) {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_GOOGLE_CLOUD_SHELL');
    } else {
      setFormState(agentCount ? 'SUBMITTED' : 'SUBMITTED_NO_AGENTS');
    }
    if (!error) {
      setSavedPackagePolicy(data.item);
      const hasAgentsAssigned = agentCount && agentPolicy;
      if (!hasAgentsAssigned && hasAzureArmTemplate) {
        setFormState('SUBMITTED_AZURE_ARM_TEMPLATE');
        return;
      }
      if (!hasAgentsAssigned && hasCloudFormation) {
        setFormState('SUBMITTED_CLOUD_FORMATION');
        return;
      }
      if (!hasAgentsAssigned && hasGoogleCloudShell) {
        setFormState('SUBMITTED_GOOGLE_CLOUD_SHELL');
        return;
      }
      if (!hasAgentsAssigned) {
        setFormState('SUBMITTED_NO_AGENTS');
        return;
      }
      onSaveNavigate(data.item);
      notifications.toasts.addSuccess({
        title: _i18n.i18n.translate('xpack.fleet.createPackagePolicy.addedNotificationTitle', {
          defaultMessage: `'{packagePolicyName}' integration added.`,
          values: {
            packagePolicyName: packagePolicy.name
          }
        }),
        text: hasAgentsAssigned ? _i18n.i18n.translate('xpack.fleet.createPackagePolicy.addedNotificationMessage', {
          defaultMessage: `Fleet will deploy updates to all agents that use the '{agentPolicyName}' policy.`,
          values: {
            agentPolicyName: agentPolicy.name
          }
        }) : undefined,
        'data-test-subj': 'packagePolicyCreateSuccessToast'
      });
    } else {
      if ((0, _services.isVerificationError)(error)) {
        setFormState('VALID'); // don't show the add agent modal
        const forceInstall = await confirmForceInstall(packagePolicy.package);
        if (forceInstall) {
          // skip creating the agent policy because it will have already been successfully created
          onSubmit({
            overrideCreatedAgentPolicy: createdPolicy,
            force: true
          });
        }
        return;
      }
      notifications.toasts.addError(error, {
        title: 'Error'
      });
      setFormState('VALID');
    }
  }, [formState, hasErrors, agentCount, selectedPolicyTab, packagePolicy, notifications.toasts, agentPolicy, onSaveNavigate, confirmForceInstall, newAgentPolicy, updatePackagePolicy, withSysMonitoring, packageInfo]);
  return {
    agentPolicy,
    updateAgentPolicy,
    packagePolicy,
    updatePackagePolicy,
    savedPackagePolicy,
    onSubmit,
    formState,
    setFormState,
    hasErrors,
    validationResults,
    setValidationResults,
    hasAgentPolicyError,
    setHasAgentPolicyError,
    isInitialized,
    // TODO check
    navigateAddAgent,
    navigateAddAgentHelp
  };
}