"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const onedrive_api_1 = require("./onedrive-api");
const locale_1 = require("./locale");
const Setting_1 = require("./models/Setting");
const Synchronizer_1 = require("./Synchronizer");
const BaseSyncTarget_1 = require("./BaseSyncTarget");
const { parameters } = require('./parameters.js');
const { FileApi } = require('./file-api.js');
const { FileApiDriverOneDrive } = require('./file-api-driver-onedrive.js');
class SyncTargetOneDrive extends BaseSyncTarget_1.default {
    static id() {
        return 3;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
    constructor(db, options = null) {
        super(db, options);
        this.api_ = null;
    }
    static unsupportedPlatforms() {
        // Web: The login UI doesn't work.
        return ['web'];
    }
    static targetName() {
        return 'onedrive';
    }
    static label() {
        return (0, locale_1._)('OneDrive');
    }
    static description() {
        return 'A file hosting service operated by Microsoft as part of its web version of Office.';
    }
    static supportsSelfHosted() {
        return false;
    }
    async isAuthenticated() {
        return !!this.api().auth();
    }
    syncTargetId() {
        return SyncTargetOneDrive.id();
    }
    isTesting() {
        const p = parameters();
        return !!p.oneDriveTest;
    }
    oneDriveParameters() {
        const p = parameters();
        if (p.oneDriveTest)
            return p.oneDriveTest;
        return p.oneDrive;
    }
    authRouteName() {
        return 'OneDriveLogin';
    }
    api() {
        if (this.isTesting()) {
            return this.fileApi_.driver().api();
        }
        if (this.api_)
            return this.api_;
        const isPublic = Setting_1.default.value('appType') !== 'cli' && Setting_1.default.value('appType') !== 'desktop';
        this.api_ = new onedrive_api_1.default(this.oneDriveParameters().id, this.oneDriveParameters().secret, isPublic);
        // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
        this.api_.on('authRefreshed', (a) => {
            this.logger().info('Saving updated OneDrive auth.');
            Setting_1.default.setValue(`sync.${this.syncTargetId()}.auth`, a ? JSON.stringify(a) : null);
        });
        let auth = Setting_1.default.value(`sync.${this.syncTargetId()}.auth`);
        if (auth) {
            try {
                auth = JSON.parse(auth);
            }
            catch (error) {
                this.logger().warn('Could not parse OneDrive auth token');
                this.logger().warn(error);
                auth = null;
            }
            this.api_.setAuth(auth);
        }
        return this.api_;
    }
    async initFileApi() {
        let context = Setting_1.default.value(`sync.${this.syncTargetId()}.context`);
        context = context === '' ? null : JSON.parse(context);
        let accountProperties = context ? context.accountProperties : null;
        const api = this.api();
        if (!accountProperties) {
            accountProperties = await api.execAccountPropertiesRequest();
            if (context) {
                context.accountProperties = accountProperties;
            }
            else {
                context = { accountProperties: accountProperties };
            }
            Setting_1.default.setValue(`sync.${this.syncTargetId()}.context`, JSON.stringify(context));
        }
        api.setAccountProperties(accountProperties);
        const appDir = await this.api().appDirectory();
        // the appDir might contain non-ASCII characters
        // /[^\u0021-\u00ff]/ is used in Node.js to detect the unescaped characters.
        // See https://github.com/nodejs/node/blob/bbbf97b6dae63697371082475dc8651a6a220336/lib/_http_client.js#L176
        // eslint-disable-next-line prefer-regex-literals -- Old code before rule was applied
        const baseDir = RegExp(/[^\u0021-\u00ff]/).exec(appDir) !== null ? encodeURI(appDir) : appDir;
        const fileApi = new FileApi(baseDir, new FileApiDriverOneDrive(this.api()));
        fileApi.setSyncTargetId(this.syncTargetId());
        fileApi.setLogger(this.logger());
        return fileApi;
    }
    async initSynchronizer() {
        try {
            if (!(await this.isAuthenticated()))
                throw new Error('User is not authenticated');
            return new Synchronizer_1.default(this.db(), await this.fileApi(), Setting_1.default.value('appType'));
        }
        catch (error) {
            BaseSyncTarget_1.default.dispatch({ type: 'SYNC_REPORT_UPDATE', report: { errors: [error] } });
            throw error;
        }
    }
}
exports.default = SyncTargetOneDrive;
//# sourceMappingURL=SyncTargetOneDrive.js.map