namespace ti_common.file {
    'use strict';

    let fs = require('fs');

    export class NWFile extends ti_common.file.File {
        static TYPE: string = 'NWFile';
        constructor(
            private $q,
            name: string,
            size: number = null,
            isLocal: boolean = true) {
            super(name, NWFile.TYPE, size, isLocal);
        }

        private bufferToBlob(buffer: Buffer) {
            return this.$q((resolve, reject) => {
                let ab = new ArrayBuffer(buffer.length);
                let uint8array = new Uint8Array(ab);
                for (let i = 0; i < buffer.length; ++i) {
                    uint8array[i] = buffer[i];
                }
                resolve(new Blob([uint8array]));
            });
        }

        private blobToBuffer(blob: Blob) {
            return this.$q((resolve, reject) => {
                let fileReader = new FileReader();
                fileReader.onload = function () {
                    let buffer = new Buffer(this.result);
                    resolve(buffer);
                };
                fileReader.readAsArrayBuffer(blob);
            });
        }
        // set the file contents
        setContents(contents: Content): angular.IPromise<string> {
            return this.$q((resolve, reject) => {
                let data = contents;
                if (contents instanceof Blob) {
                    data = this.blobToBuffer(contents);
                }
                fs.writeFileSync(this.path, data);
                resolve('file saved to ' + this.path);
            });
        }

        // get the contents of the file
        getContents(contentType?: ContentType): angular.IPromise<Content> {
            return this.$q((resolve, reject) => {
                if (!contentType || contentType === ContentType.Text) {
                    resolve(fs.readFileSync(this.path, 'utf-8'));
                } else {//BLOB
                    resolve(this.bufferToBlob(fs.readFileSync(this.path)));
                }
            });
        }

        delete(): angular.IPromise<boolean> {
            return this.$q((resolve) => {
                resolve(fs.unlinkSync(this.path));
            });
        }
    }


    class NWFileFactory implements IFileFactory {
        static $inject = ['$q'];
        constructor(private $q: angular.IQService) {
        }

        create = (path: string) => {
            let size = null;
            try {
                return new NWFile(this.$q, path, fs.statSync(path).size);
            } catch (err) {
                return new NWFile(this.$q, path);
            }
        }

        createFromJSON(obj: IFileSerializable) {

            if (obj.type !== NWFile.TYPE)
                throw obj.type + ' is not of the type of ' + NWFile.TYPE;

            return new NWFile(this.$q, obj.path, obj.size);
        }
    }


    class NWPlatformConfig implements IPlatformConfig, angular.IServiceProvider {
        // no serivce, just config
        $get() {
            return {};
        }
    }

    angular.module('ti_common').provider('ticPlatformConfig', NWPlatformConfig);

    // File factory in the cloud case
    angular.module('ti_common').service('ticFileFactory', NWFileFactory);
}