const path = require('path');
const fs = require('fs');

// 获取文件夹下所有文件
function getFilesAndFoldersInDir(filePath) {
    const filesList = [];
    const states = fs.statSync(filePath);
    if (states.isDirectory()) {
        readFile(filePath, filesList);
    }

    let fileInfo = '[';
    filesList.forEach((file) => {
        fileInfo += `\n${file}`;
    });

    fileInfo += '\n]'
    return fileInfo;
}

// 遍历读取文件
function readFile(fileDir, filesList) {
    const files = fs.readdirSync(fileDir); // 需要用到同步读取
    if (files) {
        files.forEach((file) => {
            const filePath = `${fileDir}/${file}`;
            const states = fs.statSync(filePath);
            if (states.isDirectory()) {
                filesList.push(`${filePath}/`);
            } else {
                filesList.push(filePath);
            }
        });
    }
}

let native;
let pdfSdkLibDir;
function safeLoadSDKModule() {
    if (native === undefined) {
        try {
            native = require('bindings')('pdfsdk');
        } catch (e) {
            console.log("pdfsdk module not found", e.stack);

            let message = 'PDF SDK Error: [can not load node module]\n';
            message += 'bindings pdfsdk error, ';

            let pdfSdkPath = path.join(__dirname, "../build/Release")
            message += 'pdfSdkDir \n' + getFilesAndFoldersInDir(pdfSdkPath);
            message += '\n'
            message += e.stack;

            if (pdfSdkLibDir !== undefined && pdfSdkLibDir !== null) {
                try {
                    pdfSdkPath = pdfSdkLibDir;
                    const pdfSdkNode = path.join(pdfSdkPath, 'pdfsdk.node');
                    native = require(pdfSdkNode);
                } catch (error) {
                    console.log("pdfsdk.node not found");

                    message += '\nload pdfsdk.node error, ';
                    message += 'pdfSdkDir: \n' + getFilesAndFoldersInDir(pdfSdkPath);
                    message += '\n'
                    message += error.stack;
                    throw new Error(message);
                }
            } else {
                throw new Error(message);
            }
        }
    }
}

exports.setCustomLoadModuleDir = function (pdfSdkPath) {
    pdfSdkLibDir = pdfSdkPath;
}

exports.initLibrary = function() {
    safeLoadSDKModule();
    native.initLibrary()
}

exports.destroyLibrary = function() {
    native.destroyLibrary()
}

exports.newDocument = function() {
    return native.newDocument()
}

exports.setPassword = function(documentPtr, password) {
    return native.setPassword(documentPtr, password)
}

exports.loadDocument = function(documentPtr, fileName) {
    return native.loadDocument(documentPtr, fileName)
}

exports.LoadNetworkDocument = function(documentPtr, networkFileInfo, requestHeader) {
    const {fileUrl, fileKey, fileLength, pdfCacheDir} = networkFileInfo;
    console.log("loadNetworkDocument fileUrl=" + fileUrl);
    return native.loadNetworkDocument(documentPtr, fileUrl, fileKey, fileLength, pdfCacheDir, requestHeader)
}

exports.loadNetworkDocumentAsync = function(documentPtr, networkFileInfo, requestHeader) {
    const {fileUrl, fileKey, fileLength, pdfCacheDir} = networkFileInfo;
    return native.loadNetworkDocumentAsync(documentPtr, fileUrl, fileKey, fileLength, pdfCacheDir, requestHeader)
}

exports.closeDocument = function(documentPtr) {
    return native.closeDocument(documentPtr)
}

exports.getPageCount = function(documentPtr) {
    return native.getPageCount(documentPtr)
}

exports.openPage = function(documentPtr, pageIndex) {
    return native.openPage(documentPtr, pageIndex)
}

exports.closePage = function(documentPtr, pageIndex) {
    return native.closePage(documentPtr, pageIndex)
}

exports.getPageWidth = function(documentPtr, pageIndex) {
    return native.getPageWidth(documentPtr, pageIndex)
}

exports.getPageHeight = function(documentPtr, pageIndex) {
    return native.getPageHeight(documentPtr, pageIndex)
}

exports.getPageSize = function(documentPtr, pageIndex) {
    return native.getPageSize(documentPtr, pageIndex)
}

exports.getPageRotation = function(documentPtr, pageIndex) {
    return native.getPageRotation(documentPtr, pageIndex)
}

exports.renderPage = function(options) {
    const { documentPtr, pageIndex, startX, startY, width, height, annotFlag } = options;
    return native.renderPage(documentPtr, pageIndex, startX, startY, width, height, annotFlag)
}

exports.loadAndRenderPage = function(options, callbackFunc) {
    const { documentPtr, pageIndex, renderScale, annotFlag } = options;
    return native.loadAndRenderPage(documentPtr, pageIndex, renderScale, annotFlag, callbackFunc)
}

exports.cancelRenderPage = function(documentPtr, taskId ) {
    return native.cancelRenderPage(documentPtr, taskId)
}

exports.getBookmark = function(documentPtr) {
    return native.getBookmark(documentPtr)
}

exports.getPageAllText = function(documentPtr, pageIndex) {
    return native.getPageAllText(documentPtr, pageIndex)
}

exports.getTextByIndex = function(documentPtr, pageIndex, charIndex, charCount) {
    return native.getTextByIndex(documentPtr, pageIndex, charIndex, charCount)
}

exports.getTextCharBoxByCharIndex = function(documentPtr, pageIndex, charIndex) {
    return native.getTextCharBoxByCharIndex(documentPtr, pageIndex, charIndex)
}

exports.getPageAllTextCharBox = function(documentPtr, pageIndex) {
    return native.getPageAllTextCharBox(documentPtr, pageIndex)
}

exports.getPageTextCharCount = function(documentPtr, pageIndex) {
    return native.getPageTextCharCount(documentPtr, pageIndex)
}

exports.getTextCharIndexAtPos = function(documentPtr, pageIndex, x, y, xTolerance, yTolerance) {
    return native.getTextCharIndexAtPos(documentPtr, pageIndex, x, y, xTolerance, yTolerance)
}

exports.getPageChars = function(documentPtr, pageIndex, flag) {
    return native.getPageChars(documentPtr, pageIndex, flag)
}

exports.searchText = function(documentPtr, keyword) {
    return native.searchText(documentPtr, keyword)
}

//编辑相关接口绑定
exports.createNewDocument = function() {
    return native.createNewDocument()
}

exports.setPageRotation = function(documentPtr, pageIndex, rotation) {
    return native.setPageRotation(documentPtr, pageIndex, rotation)
}

exports.addPage = function(documentPtr, pageIndex, pageWidth, pageHeight) {
    return native.addPage(documentPtr, pageIndex, pageWidth, pageHeight)
}

exports.deletePage = function(options) {
    const { documentPtr, pageIndex } = options;
    return native.deletePage(documentPtr, pageIndex)
}

exports.addJpegAndPngImage = function(documentPtr, pagePtr, fileName, isJpeg, matrixA, matrixB, matrixC, matrixD, matrixE, matrixF) {
    return native.addJpegAndPngImage(documentPtr, pagePtr, fileName, isJpeg, matrixA, matrixB, matrixC, matrixD, matrixE, matrixF)
}

exports.addImageFromBytes = function(documentPtr, pagePtr, data, stride, width, height, matrixA, matrixB, matrixC, matrixD, matrixE, matrixF) {
    return native.addImageFromBytes(documentPtr, pagePtr, data, stride, width, height, matrixA, matrixB, matrixC, matrixD, matrixE, matrixF)
}

exports.importPages = function(destDocumentPtr, srcDocumentPtr, pageRange, insertIndex) {
    return native.importPages(destDocumentPtr, srcDocumentPtr, pageRange, insertIndex)
}

exports.generateContent = function(documentPtr, pagePtr) {
    return native.generateContent(documentPtr, pagePtr)
}

exports.saveAsCopy = function(documentPtr, savePath) {
    return native.saveAsCopy(documentPtr, savePath)
}

exports.saveWithPassword = function(documentPtr, savePath, userPassword) {
    return native.saveWithPassword(documentPtr, savePath, userPassword)
}

exports.addWatermark = function(documentPtr, watermarkAnnot) {
    return native.addWatermark(documentPtr, watermarkAnnot)
}

exports.addHighLightStrikeOutUnderLineAnnotation = function(documentPtr, pointsAnnot) {
    return native.addHighLightStrikeOutUnderLineAnnotation(documentPtr, pointsAnnot)
}

exports.addInkLineSquareCircleAnnotation = function(documentPtr, inkAnnot) {
    return native.addInkLineSquareCircleAnnotation(documentPtr, inkAnnot)
}

exports.addStampAnnotation = function(documentPtr, stampAnnot) {
    return native.addStampAnnotation(documentPtr, stampAnnot)
}

exports.addFreeTextAnnotation = function(documentPtr, freeTextAnnot) {
    return native.addFreeTextAnnotation(documentPtr, freeTextAnnot)
}

exports.addLinkAnnotation = function(documentPtr, linkAnnot) {
    return native.addLinkAnnotation(documentPtr, linkAnnot)
}

exports.addTextAnnotation = function(documentPtr, textAnnot) {
    return native.addTextAnnotation(documentPtr, textAnnot)
}

exports.getPageAnnotation = function(documentPtr, pageIndex, pageScale, onlyQuark, cachePath) {
    return native.getPageAnnotation(documentPtr, pageIndex, pageScale, onlyQuark, cachePath)
}

exports.getWatermarkAnnot = function(documentPtr, pageIndex, onlyQuark) {
    return native.getWatermarkAnnot(documentPtr, pageIndex, onlyQuark)
}

exports.removeAnnot = function(documentPtr, pageIndex, annotPtr) {
    return native.removeAnnot(documentPtr, pageIndex, annotPtr)
}

exports.closeAnnot = function(documentPtr, pageIndex, annotPtr) {
    return native.closeAnnot(documentPtr, pageIndex, annotPtr)
}

exports.getImageObjectAtPosition = function(options) {
    const { documentPtr, pageIndex, x, y } = options;
    return native.getImageObjectAtPosition(documentPtr, pageIndex, x, y)
}

exports.saveImageObjectToPng = function(options) {
    const { documentPtr, pageIndex, imageObjIndex, path } = options;
    return native.saveImageObjectToPng(documentPtr, pageIndex, imageObjIndex, path)
}

exports.exportImage = function(options) {
    const { documentPtr, pageIndex, imageObjIndex, path, maxWidth, maxHeight } = options;
    return native.exportImage(documentPtr, pageIndex, imageObjIndex, path, maxWidth, maxHeight)
}

exports.getPageBoundingBox = function(options) {
    const { documentPtr, pageIndex } = options;
    return native.getPageBoundingBox(documentPtr, pageIndex)
}

exports.getPageBlocks = function(options) {
    const { documentPtr, pageIndex, cacheDir } = options;
    return native.getPageBlocks(documentPtr, pageIndex, cacheDir )
}

exports.getSvgInfo = function(options) {
    const { documentPtr, pageIndex, blockJson } = options;
    return native.getSvgInfo(documentPtr, pageIndex, blockJson)
}

exports.updateDocument = function(options) {
    const { documentPtr, contentJson, resKeys, resValues, resCount } = options;
    return native.updateDocument(documentPtr, contentJson, resKeys, resValues, resCount)
}

exports.insertContentWatermark = function(options) {
    const { documentPtr, watermarkJson } = options;
    return native.insertContentWatermark(documentPtr, watermarkJson)
}

exports.removeQuarkContentWatermark = function(options) {
    const { documentPtr } = options;
    return native.removeQuarkContentWatermark(documentPtr)
}

exports.getActionDest = function(options) {
    const { documentPtr, dest } = options;
    return native.getActionDest(documentPtr, dest)
}

exports.enabledHttpRequestDebug = function(options) {
    const { documentPtr, proxyUrl } = options;
    return native.enabledHttpRequestDebug(documentPtr, proxyUrl)
}

exports.renderPageBlock = function(options) {
    const { documentPtr, pageIndex, startX, startY, bitmapWidth, bitmapHeight, pageWidth, pageHeight, annotFlag, renderId = null } = options;
    return native.renderPageBlock(documentPtr, pageIndex, startX, startY, bitmapWidth, bitmapHeight, pageWidth, pageHeight, annotFlag, renderId)
}

exports.getDocumentId = function(documentPtr) {
    return native.getDocumentId(documentPtr)
}

/**
 * @api
 * @deprecated 后续版本废弃，请使用downloadDocument下载pdf文件
 * @see downloadDocument
 * @param {Object} options { documentPtr:0, url:null, fileKey:null, length:0, cacheDir:null, requestHeader = {} }
 * @returns {Object} {'status':0, 'path':''}
 */
exports.downloadFile = function(options) {
    const { documentPtr = 0, url = null, fileKey = null, length = 0, cacheDir = null, requestHeader = {} } = options;
    return native.downloadDocument(documentPtr, url, fileKey, length, cacheDir, requestHeader);
}

exports.downloadDocument = function(options) {
    const { documentPtr = 0, url = null, fileKey = null, length = 0, cacheDir = null, requestHeader = {} } = options;
    return native.downloadDocument(documentPtr, url, fileKey, length, cacheDir, requestHeader);
}

exports.setCacheDir = function(options) {
    const { cacheDir = null, } = options;
    native.setCacheDir(cacheDir)
}

exports.download= function(options) {
    const { url = null, targetDir = null, fileName = null, requestHeader = {}, progressCallback} = options;
    return native.download(url, targetDir, fileName, requestHeader, progressCallback);
}

exports.getRenderPageTime = function(options) {
    const { renderId } = options;
    return native.getRenderPageTime(renderId);
}

exports.unzip = function(options) {
    const { zipFile, unzipDir } = options;
    return native.unzip(zipFile, unzipDir);
}
exports.getSystemFontInfos = function (options) {
    const { documentPtr, cacheDir } = options;
    return native.getSystemFontInfos(documentPtr, cacheDir);
}

exports.scanFontInfo = function (options) {
    const { documentPtr, callback } = options;
    return native.scanFontInfo(documentPtr, callback);
}

exports.addScanFontPath = function (options) {
    const { documentPtr, path } = options;
    return native.addScanFontPath(documentPtr, path);
}

exports.scanFontFile = function (options) {
    const { documentPtr, path } = options;
    return native.scanFontFile(documentPtr, path);
}

exports.scanFontPath = function (options) {
    const { documentPtr, path } = options;
    return native.scanFontPath(documentPtr, path);
}

exports.getTempDownloadPath = function (options) {
    const { documentPtr } = options
    return native.getTempDownloadPath(documentPtr);
}

exports.cleanCacheFiles = function (options) {
    const { cacheDir, retainedCount, cleanIntervalTime} = options
    return native.cleanCacheFiles(cacheDir, retainedCount, cleanIntervalTime);
}

exports.getFontCaches = function (options) {
    const { cacheDir} = options
    return native.getFontCaches(cacheDir);
}

exports.readFileBuffer = function (options) {
    const { path } = options
    return native.readFileBuffer(path);
}



// module.exports = exports = pdfsdk