PUT /files/util/json_utils.js HTTP/1.1
Host: 127.0.0.1
Accept-Encoding: identity
Content-Length: 2448
Content-MD5: oBbPCNwC/IDlkt8NNdVHpw==
Expect: 100-continue
Date: Thu, 08 Dec 2016 13:02:38 GMT
User-Agent: aws-cli/1.11.26 Python/2.7.10 Darwin/16.1.0 botocore/1.4.83
Content-Type: application/javascript
Authorization: AWS 123:ns0+nY/FdB3rrCvaF/X9Ro1VsJk=

'use strict';

const _ = require('lodash');
const fs = require('fs');

const dbg = require('./debug_module')(__filename);
const Semaphore = require('./semaphore');
const P = require('./promise');

class JsonWrapper {
    constructor(json_path) {
        this.json_path = json_path;
        this.json_sem = new Semaphore(1);
    }


    read() {

        return P.resolve().then(() => {
            if (!this.json_path) return {};
            // maybe we can change to allow multiple readers if necessary.
            return this.json_sem.surround(() => fs.readFileAsync(this.json_path))
                .then(data => JSON.parse(data))
                .catch(err => {
                    if (err.code === 'ENOENT') {
                        dbg.warn(`could not find json file ${this.json_path}. returning empty data`);
                        return {};
                    }
                    dbg.error(`error when trying to read json file ${this.json_path}. ${err}`);
                    throw err;
                });
        });
    }

    update(params) {
        return P.resolve().then(() => {
            if (!this.json_path) return;
            // serialize json updates with Sempahore(1)
            return this.json_sem.surround(() => {
                dbg.log0(`updating json file ${this.json_path} with params: ${params}`);
                return fs.readFileAsync(this.json_path)
                    .then(data => {
                        const json_obj = JSON.parse(data);
                        dbg.log1(`old values in json file ${this.json_path}: ${json_obj}`);
                        _.assign(json_obj, params);
                        return json_obj;
                    }, err => {
                        if (err.code === 'ENOENT') {
                            dbg.log0(`could not find json file ${this.json_path}. creating new one...`);
                            return {};
                        } else {
                            throw err;
                        }
                    })
                    .then(json_obj => {
                        _.assign(json_obj, params);
                        const data = JSON.stringify(json_obj);
                        dbg.log1(`writing new values to json file ${this.json_path}: ${json_obj}`);
                        return fs.writeFileAsync(this.json_path, data);
                    });
            });
        });
    }
}


exports.JsonWrapper = JsonWrapper;
