"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.storeInvocationDescriptor = exports.storageKey = exports.normalizeInvocationDescriptor = exports.loadInvocationDescriptor = exports.getReportViewerPath = exports.getExportViewerPath = exports.createInvocationData = exports.VIEWER_WINDOW_NAME = void 0;
var _immutable = _interopRequireDefault(require("immutable"));
var _get = _interopRequireDefault(require("lodash/get"));
var _upperFirst = _interopRequireDefault(require("lodash/upperFirst"));
var _qs = _interopRequireDefault(require("qs"));
var _configHelpers = require("./configHelpers");
var _dataTypes = require("../constants/dataTypes");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* global window */

const VIEWER_WINDOW_NAME = undefined;
exports.VIEWER_WINDOW_NAME = VIEWER_WINDOW_NAME;
const storageKey = 'cspace-ui-invocation';
exports.storageKey = storageKey;
const prepareIncludeFields = (config, recordType, includeFields) => {
  if (includeFields) {
    return {
      field: includeFields.filter(field => !!field).flatMap(field => {
        const fieldSegments = field.split('/');
        const fieldDescriptor = (0, _get.default)(config, ['recordTypes', recordType, 'fields', 'document', ...fieldSegments]);
        const fieldDataType = fieldDescriptor && (0, _configHelpers.getFieldDataType)(fieldDescriptor);
        const [schema, ...path] = fieldSegments;
        const partName = schema.substring(schema.indexOf(':') + 1);
        const fieldSpec = `${partName}:${path.join('/')}`;
        if (fieldDataType === _dataTypes.DATA_TYPE_STRUCTURED_DATE) {
          // TODO: Do this for export only? Currently don't know at this point if this is an export.
          // Will need an additional arg.

          // For struct date groups, append dateDisplayDate to the field path, and specify the
          // group name as the name. This causes exports to use the group name as the column name,
          // but the display date as the value, which is expected by the converter tool.

          return {
            '@name': fieldSegments[fieldSegments.length - 1],
            '.': `${fieldSpec}/dateDisplayDate`
          };
        }
        if ((0, _configHelpers.isAutocompleteField)(fieldDescriptor)) {
          // TODO: Do this for export only. Currently don't know at this point if this is an export.
          // Will need an additional arg.

          // For authority-controlled fields, if values can be sourced from multiple authorities,
          // create a separate column for each authority. This is expected by the converter tool.

          const fieldName = path[path.length - 1];
          const sourceSpec = (0, _get.default)(fieldDescriptor, [_configHelpers.configKey, 'view', 'props', 'source']);
          const sources = sourceSpec.split(',');
          return sources.map(source => {
            const [authority, vocabulary] = source.split('/');
            const authorityConfig = (0, _get.default)(config, ['recordTypes', authority]);
            if (authorityConfig) {
              const authorityServicePath = (0, _get.default)(authorityConfig, ['serviceConfig', 'servicePath']);
              const vocabularyServicePath = (0, _get.default)(authorityConfig, ['vocabularies', vocabulary, 'serviceConfig', 'servicePath']);
              if (vocabularyServicePath) {
                const match = vocabularyServicePath.match(/urn:cspace:name\((.*?)\)/);
                const vocabularyShortId = match ? match[1] : '';
                return {
                  '@name': `${fieldName}${(0, _upperFirst.default)(authority)}${(0, _upperFirst.default)(vocabulary)}`,
                  '.': `${fieldSpec}[contains(., ':${authorityServicePath}:name(${vocabularyShortId}):')]`
                };
              }
            }
            return null;
          }).filter(item => !!item);
        }
        return fieldSpec;
      })
    };
  }
  return undefined;
};
const prepareParams = params => {
  if (params) {
    const paramPairs = [];
    Object.keys(params).forEach(key => {
      const value = params[key];
      if (Array.isArray(value)) {
        value.forEach(v => paramPairs.push({
          key,
          value: v
        }));
      } else {
        paramPairs.push({
          key,
          value
        });
      }
    });
    if (paramPairs.length > 0) {
      return {
        param: paramPairs
      };
    }
  }
  return undefined;
};
const createInvocationData = (config, invocationDescriptor, params) => {
  const {
    includeFields,
    mode,
    outputMIME,
    recordType: invocationRecordType,
    csid: invocationCsid
  } = invocationDescriptor.toJS();
  const invocationContext = {
    mode,
    outputMIME,
    includeFields: prepareIncludeFields(config, invocationRecordType, includeFields),
    params: prepareParams(params),
    docType: (0, _get.default)(config, ['recordTypes', invocationRecordType, 'serviceConfig', 'objectName'])
  };
  if (mode === 'single') {
    invocationContext.singleCSID = invocationCsid;
  } else if (mode === 'list') {
    invocationContext.listCSIDs = {
      csid: invocationCsid
    };
  } else if (mode === 'group') {
    invocationContext.groupCSID = invocationCsid;
  }
  return {
    'ns2:invocationContext': {
      '@xmlns:ns2': 'http://collectionspace.org/services/common/invocable',
      ...invocationContext
    }
  };
};
exports.createInvocationData = createInvocationData;
const normalizeInvocationDescriptor = (invocationDescriptor, invocationMetadata) => {
  let normalizedInvocationDescriptor = invocationDescriptor;
  if (!normalizedInvocationDescriptor) {
    normalizedInvocationDescriptor = _immutable.default.Map();
  }
  const outputMIME = normalizedInvocationDescriptor.get('outputMIME');
  if (!outputMIME && invocationMetadata) {
    const defaultOutputMIME = invocationMetadata.getIn(['document', 'ns2:reports_common', 'outputMIME']) || 'application/pdf';
    normalizedInvocationDescriptor = normalizedInvocationDescriptor.set('outputMIME', defaultOutputMIME);
  }
  return normalizedInvocationDescriptor;
};
exports.normalizeInvocationDescriptor = normalizeInvocationDescriptor;
const getReportViewerPath = (config, reportCsid, invocationDescriptor, reportParams) => {
  const {
    basename
  } = config;
  const reportParamsJson = reportParams && JSON.stringify(reportParams);
  const queryParams = {
    mode: invocationDescriptor.get('mode'),
    csid: invocationDescriptor.get('csid'),
    outputMIME: invocationDescriptor.get('outputMIME'),
    recordType: invocationDescriptor.get('recordType'),
    params: reportParamsJson
  };
  return `${basename || ''}/report/${reportCsid}?${_qs.default.stringify(queryParams, {
    arrayFormat: 'brackets'
  })}`;
};

// export const getExportViewerPath = (config, invocationDescriptor) => {
//   const {
//     basename,
//   } = config;

//   const csid = invocationDescriptor.get('csid');
//   const includeFields = invocationDescriptor.get('includeFields');

//   const queryParams = {
//     mode: invocationDescriptor.get('mode'),
//     csid: Immutable.List.isList(csid) ? csid.toJS() : csid,
//     outputMIME: invocationDescriptor.get('outputMIME'),
//     recordType: invocationDescriptor.get('recordType'),
//     vocabulary: invocationDescriptor.get('vocabulary'),
//     includeFields: Immutable.List.isList(includeFields) ? includeFields.toJS() : includeFields,
//   };

//   return `${basename || ''}/export?${qs.stringify(queryParams, { arrayFormat: 'brackets' })}`;
// };
exports.getReportViewerPath = getReportViewerPath;
const getExportViewerPath = config => {
  const {
    basename
  } = config;
  return `${basename || ''}/export`;
};
exports.getExportViewerPath = getExportViewerPath;
const storeInvocationDescriptor = invocationDescriptor => {
  window.localStorage.setItem(storageKey, JSON.stringify(invocationDescriptor.toJS()));
};
exports.storeInvocationDescriptor = storeInvocationDescriptor;
const loadInvocationDescriptor = deleteAfterLoad => {
  const serializedInvocationDescriptor = window.localStorage.getItem(storageKey);
  let invocationDescriptor = null;
  if (serializedInvocationDescriptor) {
    try {
      invocationDescriptor = _immutable.default.fromJS(JSON.parse(serializedInvocationDescriptor));
    } catch (error) {
      invocationDescriptor = null;
    }
  }
  if (deleteAfterLoad) {
    window.localStorage.removeItem(storageKey);
  }
  return invocationDescriptor;
};
exports.loadInvocationDescriptor = loadInvocationDescriptor;