#!/usr/bin/env node

require('dotenv').config();
const fs = require('fs');
const sendEmail = require('./lib/send-email');
const cacheFile = __dirname + '/last-seen-committees.json';
const Browser = require('zombie');
const browser = new Browser({waitDuration: '30s'});

browser.visit('https://efiling.ocf.dc.gov/Disclosure')
    .then(getTypes)
    .then(getLastSeen)
    .then(findNewRecords)
    .then(sendNotification);

function getTypes() {
    const types = [];
    const options = browser.field('#FilerTypeId').options;
    for (const option of options) {
        if (option.value) {
            types.push(option.text);
        }
    }
    return types;
}

function getLastSeen(types) {
    return new Promise(function (resolve, reject) {
        fs.readFile(cacheFile, function (err, json) {
            let lastSeen = {};
            if (err) {
                if (err.code !== 'ENOENT') {
                    return reject(err);
                }
            }
            else {
                lastSeen = JSON.parse(json);
            }
            for (const type of types) {
                if (!lastSeen[type]) {
                    lastSeen[type] = null;
                }
            }
            return resolve(lastSeen);
        });
    });
}

async function findNewRecords(lastSeen) {
    const allNewRecords = {};
    let changed = false;
    for (const [type, lastSeenId] of Object.entries(lastSeen)) {
        const newRecords = await findNewRecordsForType(type, lastSeenId);
        if (newRecords.length) {
            lastSeen[type] = newRecords[0].Id;
            changed = true;
            allNewRecords[type] = newRecords;
        }
    }
    if (changed) {
        fs.writeFileSync(cacheFile, JSON.stringify(lastSeen, null, 2));
    }
    return allNewRecords;
}

function findNewRecordsForType(type, lastSeenId) {
    return browser.select('#FilerTypeId', type)
        .then(pause)
        .then(() => browser.click('#btnSubmitSearch'))
        .then(getSearchData)
        .then(function (records) {
            const newRecords = [];
            for (const record of records) {
                if (lastSeenId && record.Id <= lastSeenId) {
                    break;
                }
                newRecords.push(record);
            }
            return newRecords;
        });
}

function pause() {
    return new Promise(resolve => setTimeout(resolve, 5000));
}

function getSearchData() {
    let i = browser.resources.length;
    while (i > 0) {
        i--;
        const resource = browser.resources[i];
        if (resource.request.url.match(/\/Search$/)) {
            return JSON.parse(resource.response.body).data;
        }
    }
    throw new Error('Search data not found');
}

function sendNotification(allNewRecords) {
    let text = '';
    let count = 0;
    for (const [type, records] of Object.entries(allNewRecords)) {
        text += type + '\n';
        for (const record of records) {
            text += '\n';
            for (const [key, value] of Object.entries(record)) {
                text += `  ${key}: ${value}\n`;
            }
            count++;
        }
        text += '\n';
    }
    if (count) {
        sendEmail({
            text,
            from: process.env.EMAIL_SENDER,
            to: process.env.EMAIL_RECIPIENT,
            subject: `${count} new OCF filing${count === 1 ? '' : 's'}`,
        });
    }
}

@@ -181,23 +181,31 @@
 ;%0Aconst 
+%7Bcreate
 Browser
+%7D
  = requi
@@ -212,14 +212,21 @@
 re('
-zombie
+./lib/browser
 ');%0A
@@ -245,20 +245,22 @@
 r = 
-new 
+create
 Browser(
 %7Bwai
@@ -259,106 +259,98 @@
 ser(
-%7BwaitDuration: '30s'%7D);%0A%0Abrowser.visit('https://efiling.ocf.dc.gov/Disclosure')%0A    .then(
+);%0A%0Amain().catch(console.trace);%0A%0Aasync function main() %7B%0A    const types = await 
 getTypes
 )%0A  
@@ -349,110 +349,256 @@
 ypes
-)
+();
 %0A    
-.then(getLastSeen)%0A    .then(findNewRecords)%0A    .then(sendNotification);%0A%0Afunction getTypes() %7B
+const lastSeen = await getLastSeen(types);%0A    const allNewRecords = await findNewRecords(lastSeen);%0A    await sendNotification(allNewRecords);%0A%7D%0A%0Aasync function getTypes() %7B%0A    await browser.visit('https://efiling.ocf.dc.gov/Disclosure');
 %0A   
@@ -1941,24 +1941,30 @@
 Records;%0A%7D%0A%0A
+async 
 function fin
@@ -2006,22 +2006,21 @@
 ) %7B%0A    
-return
+await
  browser
@@ -2052,49 +2052,19 @@
 ype)
+;
 %0A
- 
     
-   .then(pause)%0A        .then(() =%3E
+await
  bro
@@ -2097,82 +2097,47 @@
 ch')
-)
+;
 %0A    
-    .then(getSearchData)%0A        .then(function (records) %7B%0A        
+const records = getSearchData();%0A
     
@@ -2159,24 +2159,16 @@
 s = %5B%5D;%0A
-        
     for 
@@ -2191,32 +2191,24 @@
  records) %7B%0A
-        
         if (
@@ -2260,24 +2260,16 @@
         
- 
-       
 break;%0A 
@@ -2275,36 +2275,26 @@
         
-  
-      %7D%0A  
+%7D%0A
         
       ne
@@ -2285,22 +2285,16 @@
         
-      
 newRecor
@@ -2314,34 +2314,18 @@
 d);%0A    
-        %7D%0A        
+%7D%0A
     retu
@@ -2343,104 +2343,8 @@
 ds;%0A
-        %7D);%0A%7D%0A%0Afunction pause() %7B%0A    return new Promise(resolve =%3E setTimeout(resolve, 5000));%0A
 %7D%0A%0Af

rewrite disclosure-monitor.js to use async/await more