<?php

require_once 'form_processor.civix.php';
use CRM_FormProcessor_ExtensionUtil as E;

use \Symfony\Component\DependencyInjection\ContainerBuilder;
use \Civi\FormProcessor\Symfony\Component\DependencyInjection\DefinitionAdapter;

/**
 * Implements hook_civicrm_container()
 *
 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_container/
 */
function form_processor_civicrm_container(ContainerBuilder $container) {
  // Register the TypeFactory
  $typeFactoryDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\Type\Factory');
  $container->setDefinition('form_processor_type_factory', $typeFactoryDefinition);
  // Register the OutputHandlerFactory
  $outputHandlerDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\OutputHandler\Factory');
  $container->setDefinition('form_processor_output_handler_factory', $outputHandlerDefinition);
  // Register the DelayedAction Factoory
  $delayedActionFactoryDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\DelayedAction\Factory');
  $container->setDefinition('form_processor_delayed_action_factory', $delayedActionFactoryDefinition);
  // Register the validationFactory
  $validationFactoryDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\Validation\Factory');
  $validationFactoryDefinition->setFactory(['Civi\FormProcessor\Validation\Factory', 'singleton']);
  $container->setDefinition('form_processor_validation_factory', $validationFactoryDefinition);


  // Register our API Providers.
  // The API provider is used to process incoming api calls and process them
  // with the form processor logic.
  $apiKernelDefinition = $container->getDefinition('civi_api_kernel');
  $apiProviderDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\API\FormProcessor');
  $apiKernelDefinition->addMethodCall('registerApiProvider', array($apiProviderDefinition));
  $apiProviderDefaultsDefinition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\API\FormProcessorDefaults');
  $apiKernelDefinition->addMethodCall('registerApiProvider', array($apiProviderDefaultsDefinition));
  // Register APIv4 provider
  $api4Definition = DefinitionAdapter::createDefinitionClass('Civi\FormProcessor\API4\FormProcessorProvider');
  $apiKernelDefinition->addMethodCall('registerApiProvider', [$api4Definition]);



  $container->findDefinition('dispatcher')
    ->addMethodCall('addSubscriber', [new \Symfony\Component\DependencyInjection\Definition('Civi\FormProcessor\EventListener\FormatSubscriber')]);
}

/**
 * Implements hook_civicrm_alterAPIPermissions()
 *
 * All Form Processor api's are under the Administer CiviCRM permission.
 * Except for the FormProcessorExecutor api.
 *
 * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_alterAPIPermissions/
 */
function form_processor_civicrm_alterAPIPermissions($entity, $action, &$params, &$permissions) {
    $permissions['form_processor_instance']['list'] = array();
    $permissions['form_processor_instance']['get'] = array('administer CiviCRM');
    $permissions['form_processor_instance']['create'] = array('administer CiviCRM');
    $permissions['form_processor_instance']['delete'] = array('administer CiviCRM');
    $permissions['form_processor_instance']['export'] = array('administer CiviCRM');
    $permissions['form_processor_instance']['import'] = array('administer CiviCRM');
    $permissions['form_processor_instance']['revert'] = array('administer CiviCRM');

    $permissions['form_processor_input']['get'] = array('administer CiviCRM');
    $permissions['form_processor_input']['create'] = array('administer CiviCRM');
    $permissions['form_processor_input']['delete'] = array('administer CiviCRM');

    $permissions['form_processor_validation']['get'] = array('administer CiviCRM');
    $permissions['form_processor_validation']['create'] = array('administer CiviCRM');
    $permissions['form_processor_validation']['delete'] = array('administer CiviCRM');

    $permissions['form_processor_action']['get'] = array('administer CiviCRM');
    $permissions['form_processor_action']['create'] = array('administer CiviCRM');
    $permissions['form_processor_action']['delete'] = array('administer CiviCRM');
    $permissions['form_processor_action']['converttitletoname'] = array('administer CiviCRM');
    $permissions['form_processor_action']['validatename'] = array('administer CiviCRM');

    $permissions['form_processor_default_data_input']['get'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_input']['create'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_input']['delete'] = array('administer CiviCRM');

    $permissions['form_processor_default_data_action']['get'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_action']['create'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_action']['delete'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_action']['converttitletoname'] = array('administer CiviCRM');
    $permissions['form_processor_default_data_action']['validatename'] = array('administer CiviCRM');


    if (in_array($entity, array('form_processor', 'form_processor_defaults')) && $action != 'getactions') {
      $formProcessName = $action;
      if ($action == 'getfields' && isset($params['api_action'])) {
          $formProcessName = $params['api_action'];
      }

      $permissions[$entity][$action] = array();
      $formProcessorPermission = CRM_FormProcessor_BAO_FormProcessorInstance::getPermission($formProcessName);
      if (!empty($formProcessorPermission)) {
        $permissions[$entity][$action][] = $formProcessorPermission;
      }
    }
}

/**
 * Implementation of hook_civicrm_pageRun
 *
 * Handler for pageRun hook.
 */
function form_processor_civicrm_pageRun(&$page) {
  $f = '_' . __FUNCTION__ . '_' . get_class($page);
  if (function_exists($f)) {
    $f($page);
  }
}

function _form_processor_civicrm_pageRun_CRM_Admin_Page_Extensions(&$page) {
  _form_processor_prereqCheck();
}

function _form_processor_prereqCheck() {
  $unmet = CRM_FormProcessor_Upgrader::checkExtensionDependencies();
  CRM_FormProcessor_Upgrader::displayDependencyErrors($unmet);
}

/**
 * @return \Civi\ActionProvider\Provider
 */
function form_processor_get_action_provider() {
  $container = \Civi::container();
  if ($container->has('action_provider')) {
    $action_provider_container = $container->get('action_provider');
    return $action_provider_container->getProviderByContext('form_processor');
  }
  return null;
}

/**
 * @return \Civi\ActionProvider\Provider
 */
function form_processor_get_action_provider_for_default_data() {
  $container = \Civi::container();
  if ($container->has('action_provider')) {
    $action_provider_container = $container->get('action_provider');
    return $action_provider_container->getProviderByContext('form_processor');
  }
  return null;
}

/**
 * Implementation of hook_civicrm_navigationMenu.
 *
 * Adds Automation navigation items just before the Administer menu.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_navigationMenu
 */
function form_processor_civicrm_navigationMenu(&$params) {
  if (!_form_processor_menu_exists($params, 'Administer/automation')) {
    _form_processor_civix_insert_navigation_menu($params, 'Administer', [
      'label' => E::ts('Automation'),
      'name' => 'automation',
      'url' => NULL,
      'permission' => 'administer CiviCRM',
      'operator' => NULL,
      'separator' => 0,
    ]);
  }
  _form_processor_civix_insert_navigation_menu($params, 'Administer/automation', array(
    'label' => E::ts('Form processors'),
    'name' => 'form_processors',
    'url' => 'civicrm/admin/automation/formprocessor/#/formprocessors',
    'permission' => 'administer CiviCRM',
    'operator' => NULL,
  ));
  _form_processor_civix_navigationMenu($params);
}

/**
 * Checks whether a navigation menu item exists.
 *
 * @param array $menu - menu hierarchy
 * @param string $path - path to parent of this item, e.g. 'my_extension/submenu'
 *    'Mailing', or 'Administer/System Settings'
 * @return bool
 */
function _form_processor_menu_exists(&$menu, $path) {
  // Find an recurse into the next level down
  $found = FALSE;
  $path = explode('/', $path);
  $first = array_shift($path);
  foreach ($menu as $key => &$entry) {
    if ($entry['attributes']['name'] == $first) {
      if (empty($path)) {
        return true;
      }
      $found = _form_processor_menu_exists($entry['child'], implode('/', $path));
      if ($found) {
        return true;
      }
    }
  }
  return $found;
}


/**
 * Implements hook_civicrm_config().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_config
 */
function form_processor_civicrm_config(&$config) {
  _form_processor_civix_civicrm_config($config);
}

/**
 * Implements hook_civicrm_xmlMenu().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_xmlMenu
 */
function form_processor_civicrm_xmlMenu(&$files) {
  _form_processor_civix_civicrm_xmlMenu($files);
}

/**
 * Implements hook_civicrm_install().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_install
 */
function form_processor_civicrm_install() {
  _form_processor_civix_civicrm_install();
}

/**
 * Implements hook_civicrm_postInstall().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall
 */
function form_processor_civicrm_postInstall() {
  _form_processor_civix_civicrm_postInstall();
}

/**
 * Implements hook_civicrm_uninstall().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
 */
function form_processor_civicrm_uninstall() {
  _form_processor_civix_civicrm_uninstall();
}

/**
 * Implements hook_civicrm_enable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
 */
function form_processor_civicrm_enable() {
  _form_processor_civix_civicrm_enable();
}

/**
 * Implements hook_civicrm_disable().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
 */
function form_processor_civicrm_disable() {
  _form_processor_civix_civicrm_disable();
}

/**
 * Implements hook_civicrm_upgrade().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_upgrade
 */
function form_processor_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) {
  return _form_processor_civix_civicrm_upgrade($op, $queue);
}

/**
 * Implements hook_civicrm_managed().
 *
 * Generate a list of entities to create/deactivate/delete when this module
 * is installed, disabled, uninstalled.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_managed
 */
function form_processor_civicrm_managed(&$entities) {
  \Civi\FormProcessor\Utils\Cache::clear();
  _form_processor_civix_civicrm_managed($entities);
}

/**
 * Implements hook_civicrm_caseTypes().
 *
 * Generate a list of case-types.
 *
 * Note: This hook only runs in CiviCRM 4.4+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_caseTypes
 */
function form_processor_civicrm_caseTypes(&$caseTypes) {
  _form_processor_civix_civicrm_caseTypes($caseTypes);
}

/**
 * Implements hook_civicrm_angularModules().
 *
 * Generate a list of Angular modules.
 *
 * Note: This hook only runs in CiviCRM 4.5+. It may
 * use features only available in v4.6+.
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_angularModules
 */
function form_processor_civicrm_angularModules(&$angularModules) {
  _form_processor_civix_civicrm_angularModules($angularModules);
}

/**
 * Implements hook_civicrm_alterSettingsFolders().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_alterSettingsFolders
 */
function form_processor_civicrm_alterSettingsFolders(&$metaDataFolders = NULL) {
  _form_processor_civix_civicrm_alterSettingsFolders($metaDataFolders);
}

// --- Functions below this ship commented out. Uncomment as required. ---

/**
 * Implements hook_civicrm_preProcess().
 *
 * @link http://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_preProcess
 *
function form_processor_civicrm_preProcess($formName, &$form) {

} // */
