const FeedMe = require('feedme');
const fecha = require('fecha');
const request = require('request');
const http = require('http');

const { reduceArticle } = require('./reducers/euronews');

const logger = require('log4js').getLogger('Euronews');
logger.level = 'debug';

module.exports = {
  'getEuroNews': doGetEuroNews,
  'render': render,
  'getArticle' : doGetArticle

};

const headers = {};
const lastGood = {};

class Template {
  constructor(item) {
    // "pubdate": "Tue, 06 Feb 2018 17:05:00 +0100",
    const pubdateSrc = fecha.parse(item.pubdate, 'ddd, DD MMM YYYY HH:mm:SS ZZ');
    const pubdate = fecha.format(pubdateSrc, 'dddd MMMM Do, YYYY');
    const description = item.description.replace(/(<script(\s|\S)*?<\/script>)|(<style(\s|\S)*?<\/style>)|(<!--(\s|\S)*?-->)|(<\/?(\s|\S)*?>)/g, '');
    this.data = `<article>
<header>
<a href="${item.guid.text}">${item.title}</a>
<time class="published">${pubdate}</time>
</header>
<p class="description">${description}</p>
</article>`;
  }

  toString() {
    return this.data;
  }
}

function doGetEuroNews() {
  return new Promise((resolve, reject) => {
    logger.info('Retrieving Euronews Headlines..');

    const options = {
      'hostname': 'feeds.feedburner.com',
      'path': '/euronews/en/news/',
      'method': 'GET',
      'headers': headers
    };

    // http.get('http://feeds.feedburner.com/euronews/en/news/', (res) => {
    http.get(options, (res) => {
      const { statusCode } = res;
      const contentType = res.headers['content-type'];
      const reqLastModified = res.headers['last-modified'];

      logger.debug(res.headers);
      let error;

      logger.debug('contentType', contentType);
      if (statusCode !== 200 && statusCode !== 304)
        error = new Error('Request Failed.\n' +
                            `Status Code: ${statusCode}`);

      else if (!/^text\/xml/.test(contentType) && statusCode === 200)
        error = new Error('Invalid content-type.\n' +
                            `Expected text/xml but received ${contentType}`);

      if (error) {
        logger.error(error.message);
        // consume response data to free up memory
        res.resume();

        return reject(error);
      }

      if ( statusCode === 200) {
        headers['If-Modified-Since'] = reqLastModified;
        const parser = new FeedMe(true);
        res.pipe(parser);
        parser.on('end', () => {
          lastGood.page = parser.done();
          logger.info('Euronews page cached');
          // return resolve(parser.done());
          return resolve(lastGood.page);
        });
      }
      else if (statusCode === 304) {
        logger.info('Euronews not changed');

        return resolve(lastGood.page);
      }
    });
  });
}

function doGetArticle(guid = '') {
  const splitURL = /([--:\w?@%&+~#=]*\.[a-z]{2,4}\/{0,2})((?:[?&](?:\w+)=(?:\w+))+|[--:\w?@%&+~#=]+)?/g;
  const url = splitURL.exec(decodeURI(guid));
  logger.debug('Converting:', guid);
  // logger.debug('Split', url);

  const ampURL = `${url[1]}amp/${url[2]}`;

  return new Promise(function(resolve, reject) {
    request(ampURL, function(err, resp, body) {
      if (err)
      //  Logger.error(err);
        return reject(err);
      // Throw err;

      const output = reduceArticle(body);

      return resolve(output);
    }, function(error, response, body) {
      if (response.statusCode !== 200) {
        logger.error(response.statusCode);
        logger.error(body);

        return reject(error);
      }
    });
  });
}

function render(data) {
  logger.debug('Rendering euronews');
  // logger.debug(JSON.stringify(data));

  const html = [];
  const items = data.slice(0, 10);
  for (const item of items)
    html.push(new Template(item).toString());

  return(html.join(''));
}
