// 书单查询接口


const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const config = require('./config');
const crawlers = require('./crawler');


// 通过标题列出书单
async function listBookByTitle(title, sync) {
    let payload = {};  // 返回的数据

    if (!title) {  // 如果标题为空,拒绝查询
        payload.code = 400;
        payload.message = '标题不能为空';
        return payload;
    }

    // 对各个数据源的爬取动作
    let queries = [
        ['dangdang', crawlers.DangdangCrawler.getListByTitle]
    ]; 
    let hash = crypto.createHash('sha1').update(title).digest('hex');
    let filepath = path.join(config.CACHE_PATH, 'list', hash);  // 保存任务状态的文件路径


    // 检查是否有同标题的查询
    if (fs.existsSync(filepath)) {
        // 若有,检查该查询是否在config.CACHE_EXPIRATION_MS的时限内进行过
        if (new Date().getTime() - fs.lstatSync(filepath).mtime <= config.CACHE_EXPIRATION_MS) {
            // 若为5分钟内进行的查询,则直接采用该查询的信息
            try {
                payload = JSON.parse(fs.readFileSync(filepath).toString());
                
                // 若该查询的状态为200,则修改为304,告知客户端返回的信息为从缓存中读取的信息
                // 否则,不修改查询的状态
                if (payload.code === 200) {
                    payload.code = 304;
                    payload.message = '从缓存中读取的信息';
                }
                return payload;
            }
            catch (err) {
                fs.unlink(filepath, (err) => {
                    console.log(err);
                });
            }
        }
    }


    // 同步的查询方法
    async function Sync() {  
        let books = [];
        
        for (let i = 0; i < queries.length; ++i) {
            let result = await queries[i][1](title);
            result.forEach((book) => {
                book.provider = queries[i][0];
                books.push(book);
            });
        }

        payload.code = 200;
        payload.message = '已列出书单';
        payload.date = new Date();
        payload.books = books;

        // 将查询的结果写入文件保存
        fs.writeFile(filepath, JSON.stringify(payload), (err) => {
            if (err) {
                console.log(err);
            }
        });
    }


    // 异步的查询方法
    async function Async() {
        let books = [];

        payload.code = 206;
        payload.message = '正在列出书单';
        fs.writeFileSync(filepath, JSON.stringify(payload));  // 建立任务

        let task_count = queries.length;
        let finished_count = 0;

        queries.forEach(async (query) => {
            let result = await query[1](title);
            result.forEach((book) => {
                book.provider = query[0];
                books.push(book);
            });
            finished_count++;

            console.log(finished_count, task_count);
            if (task_count === finished_count) {
                payload.code = 200;
                payload.message = '已列出书单';
            }
            payload.date = new Date();
            payload.books = books;
            fs.writeFileSync(filepath, JSON.stringify(payload));
        });
    }

    sync ? await Sync() : Async();
    return payload;
}


async function middleware(req, res) {
    let sync = req.query['sync'];
    let title = (req.query['title'] || '').trim();

    let startedTime = new Date();
    let payload = await listBookByTitle(title, sync);
    let finidshdTime = new Date();
    payload.during = finidshdTime.getTime() - startedTime.getTime();
    res.json(payload);
}


module.exports = { middleware };