"use strict";

var _tape = _interopRequireDefault(require("tape"));

var _reduxBundler = require("redux-bundler");

var _acFhirModels = require("ac-fhir-models");

var _fhirResources = require("./fhir-resources");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const getFullFhirUrl = (datastoreName, resourceType = 'Patient', id = 'd460a980-d92f-4f2a-842e-49b648ad9453') => "https://healthcare.googleapis.com/v1/projects/anesthesia-api-stage/locations/us/datasets/AC_STAGE/fhirStores/".concat(datastoreName, "/fhir/").concat(resourceType).concat(id ? "/".concat(id) : '');

const getStore = (delay = 0) => {
  const store = (0, _reduxBundler.composeBundlesRaw)(_fhirResources.fhirResourceBundle, {
    name: 'stubs',
    getExtraArgs: store => ({
      fhirFetch: () => new Promise(resolve => {
        setTimeout(() => resolve(store.fhirResponse), delay);
      })
    })
  })();
  return store;
};

(0, _tape.default)('fhirResourceBundle', async t => {
  const store = getStore();
  const practitionersRaw = store.selectPractitionersRaw();
  t.deepEqual(store.selectPractitionersRaw(), {}, 'Should be empty object to start');
  t.equal(store.selectPractitionersRaw(), store.selectPractitionersRaw(), 'Should return the same empty object to maximize memoization'); // prep and "fetch" response

  store.fhirResponse = {
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id'
      })
    }]
  };
  await store.doFetchFhirResource('Appointment/appointment_id', 'cfd');
  t.equal(store.selectPractitionersRaw(), practitionersRaw, 'selectPractitionersRaw should not be affected by unrelated resource types');
  t.deepEqual(store.selectAppointmentsRaw(), {
    appointment_id: {
      resourceType: 'Appointment',
      id: 'appointment_id',
      orgId: 'cfd'
    }
  }, 'selectAppointmentsRaw should return items keyed by ID');
  t.equal(store.selectAppointmentsRaw(), store.selectAppointmentsRaw(), 'should return same appointments if called twice');
  const previousAppointments = store.selectAppointmentsRaw(); // prep and "fetch" response

  store.fhirResponse = {
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Patient', 'patient_id'),
      resource: _acFhirModels.patientDefinition.create({
        id: 'patient_id'
      })
    }]
  };
  await store.doFetchFhirResource('Patient/patient_id');
  t.equal(previousAppointments, store.selectAppointmentsRaw(), 'should return same object if something else has changed');
  t.end();
});
(0, _tape.default)('fhirResourceBundle handles active operations', async t => {
  // prep and "fetch" response
  const store = getStore(100);
  store.fhirResponse = {
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Patient', 'patient_id'),
      resource: _acFhirModels.patientDefinition.create({
        id: 'patient_id',
        firstName: 'bob'
      })
    }]
  };
  const promise = store.doFetchFhirResource('Patient/patient_id', 'cfd');
  t.deepEqual(store.selectPatientsRaw().patient_id, {
    resourceType: 'Patient',
    id: 'patient_id',
    activeOperation: 'load',
    orgId: 'cfd'
  }, 'should have "load" as active operation'); // let it finish

  await promise;
  t.deepEqual(store.selectPatientsRaw().patient_id, {
    resourceType: 'Patient',
    id: 'patient_id',
    name: [{
      given: ['bob']
    }],
    orgId: 'cfd'
  }, 'should now be complete and not have any active operation');
  t.end();
});
(0, _tape.default)('fhirResourceBundle handles receive resources appropriately', async t => {
  // prep and "fetch" response
  const store = getStore();
  const response = {
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_1'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_1'
      })
    }, {
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_2'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_2'
      })
    }, {
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_3'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_3'
      })
    }, {
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_4'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_4'
      })
    }]
  };
  store.doReceiveFhirResponse(response);
  t.deepEqual(store.selectAppointmentsRaw(), {
    appointment_id_1: {
      resourceType: 'Appointment',
      id: 'appointment_id_1',
      orgId: 'cfd'
    },
    appointment_id_2: {
      resourceType: 'Appointment',
      id: 'appointment_id_2',
      orgId: 'cfd'
    },
    appointment_id_3: {
      resourceType: 'Appointment',
      id: 'appointment_id_3',
      orgId: 'cfd'
    },
    appointment_id_4: {
      resourceType: 'Appointment',
      id: 'appointment_id_4',
      orgId: 'cfd'
    }
  }, 'should have received them all');
  t.end();
});
(0, _tape.default)('fhirResourceBundle.utilFindFhirResourceById()', async t => {
  // prep and "fetch" response
  const store = getStore();
  const response = {
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_1'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_1'
      })
    }, {
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_2'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_2'
      })
    }]
  };
  t.deepEqual(store.utilFindFhirResourceById('appointment_id_1'), null, 'returns null if not found');
  store.doReceiveFhirResponse(response);
  t.deepEqual(store.utilFindFhirResourceById('appointment_id_1'), {
    resourceType: 'Appointment',
    id: 'appointment_id_1'
  }, 'should be able to retrieve resource just by id');
  t.end();
});
(0, _tape.default)('extract name from full URL', t => {
  // "Only numbers, letters, underscores, hyphens, and periods are allowed"
  const validId = 'a.3-y_ZY';
  t.equal((0, _fhirResources.extractOrgId)(getFullFhirUrl(validId)), validId);
  const other = 'cfd';
  t.equal((0, _fhirResources.extractOrgId)(getFullFhirUrl(other)), other);
  t.end();
});
(0, _tape.default)('fhirResourceBundle can clear all resources except those from a single org', async t => {
  // prep and "fetch" response
  const store = getStore();
  store.doReceiveFhirResponse({
    entry: [{
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_1'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_1'
      })
    }, {
      fullUrl: getFullFhirUrl('cfd', 'Appointment', 'appointment_id_3'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_3'
      })
    }]
  }, {
    entry: [{
      fullUrl: getFullFhirUrl('other', 'Appointment', 'appointment_id_2'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_2'
      })
    }]
  }, {
    entry: [{
      fullUrl: getFullFhirUrl('third', 'Appointment', 'appointment_id_4'),
      resource: _acFhirModels.appointmentDefinition.create({
        id: 'appointment_id_4'
      })
    }]
  });
  t.deepEqual(store.selectAppointmentsRaw(), {
    appointment_id_1: {
      resourceType: 'Appointment',
      id: 'appointment_id_1',
      orgId: 'cfd'
    },
    appointment_id_2: {
      resourceType: 'Appointment',
      id: 'appointment_id_2',
      orgId: 'other'
    },
    appointment_id_3: {
      resourceType: 'Appointment',
      id: 'appointment_id_3',
      orgId: 'cfd'
    },
    appointment_id_4: {
      resourceType: 'Appointment',
      id: 'appointment_id_4',
      orgId: 'third'
    }
  }, 'should have received them all from different orgs');
  store.doClearFhirModelsNotInOrg('cfd');
  t.deepEqual(store.selectAppointmentsRaw(), {
    appointment_id_1: {
      resourceType: 'Appointment',
      id: 'appointment_id_1',
      orgId: 'cfd'
    },
    appointment_id_3: {
      resourceType: 'Appointment',
      id: 'appointment_id_3',
      orgId: 'cfd'
    }
  }, 'should have cleared all except cfd ones');
  t.end();
});