const _ = require('lodash');
const Debug = require('../helper/debug');
const debugLog = new Debug('controller:libpostal');
const logger = require('pelias-logger').get('api');

// Find field in libpostal response 
function findField(response, field, replacementField) {
  const libpostalField = response.find(f => f.label === field);

  if (libpostalField) {
    return libpostalField;
  } else if(replacementField) {
    return response.find(f => f.label === replacementField);
  } else {
    return;
  }
}


function setup(libpostalService, should_execute) {
  function controller( req, res, next ){
    // bail early if req/res don't pass conditions for execution
    if (!should_execute(req, res)) {
      return next();
    }

    const initialTime = debugLog.beginTimer(req);

    libpostalService(req, (err, response) => {
      if (err) {
        // push err.message or err onto req.errors
        req.errors.push( _.get(err, 'message', err) );

      } else {
        // figure out which field contains the probable house number, prefer house_number
        // libpostal parses some inputs, like `3370 cobbe ave`, as a postcode+street
        // so because we're treating the entire field as a street address, it's safe
        // to assume that an identified postcode is actually a house number.
        // if there's a house_number in the libpostal response, return it
        // otherwise return the postcode field (which may be undefined)
        const house_number_field = findField(response, 'house_number', 'postcode');

        // if we're fairly certain that libpostal identified a house number
        // (from either the house_number or postcode field), place it into the
        // number field and remove the first instance of that value from address
        // and assign to street
        // eg - '1090 N Charlotte St' becomes number=1090 and street=N Charlotte St
        if (house_number_field) {
          req.clean.parsed_text.number = house_number_field.value;

          // remove the first instance of the number and trim whitespace
          req.clean.parsed_text.street = _.trim(_.replace(req.clean.parsed_text.address, req.clean.parsed_text.number, ''));

          // If libpostal have parsed unit then add it for search
          const unit_field = findField(response, 'unit');
          if(unit_field) {
            req.clean.parsed_text.unit = unit_field.value;
            // Removing unit from street and trim
            req.clean.parsed_text.street = _.trim(_.replace(req.clean.parsed_text.street, req.clean.parsed_text.unit, ''));
          }

        } else {
          // otherwise no house number was identifiable, so treat the entire input
          // as a street
          req.clean.parsed_text.street = req.clean.parsed_text.address;

        }

        // the address field no longer means anything since it's been parsed, so remove it
        delete req.clean.parsed_text.address;

        debugLog.push(req, {parsed_text: response});

      }

      debugLog.stopTimer(req, initialTime);
      return next();

    });

  }

  return controller;
}

module.exports = setup;