"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const InteropService_Importer_Md_1 = require("./InteropService_Importer_Md");
const Note_1 = require("../../models/Note");
const Folder_1 = require("../../models/Folder");
const Tag_1 = require("../../models/Tag");
const shim_1 = require("../../shim");
const frontMatter_1 = require("../../utils/frontMatter");
const types_1 = require("../database/types");
const yaml = require("js-yaml");
const Logger_1 = require("@joplin/utils/Logger");
const logger = Logger_1.default.create('InteropService_Importer_Md_frontmatter');
// Maps the string labels written by the exporter back to FolderIconType enum values.
const folderIconTypeFromString = (typeStr) => {
    switch (typeStr) {
        case 'emoji': return types_1.FolderIconType.Emoji;
        case 'fontawesome': return types_1.FolderIconType.FontAwesome;
        case 'dataurl': return types_1.FolderIconType.DataUrl;
        default: return null;
    }
};
// Parses the raw YAML-parsed value into a FolderIcon. The YAML FAILSAFE_SCHEMA
// returns all values as strings and uses lowercase keys (e.g. "dataurl" instead
// of "dataUrl"), so we normalise immediately after parsing to avoid carrying two
// separate interfaces around.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- The raw YAML output is untyped
const parseRawYamlToFolderIcon = (raw) => {
    if (!raw || typeof raw !== 'object')
        return null;
    if (typeof raw.type !== 'string')
        return null;
    const iconType = folderIconTypeFromString(raw.type);
    if (iconType === null)
        return null;
    switch (iconType) {
        case types_1.FolderIconType.Emoji:
            if (!raw.emoji)
                return null;
            return { type: types_1.FolderIconType.Emoji, emoji: raw.emoji, name: '', dataUrl: '' };
        case types_1.FolderIconType.FontAwesome:
            if (!raw.name)
                return null;
            return { type: types_1.FolderIconType.FontAwesome, emoji: '', name: raw.name, dataUrl: '' };
        case types_1.FolderIconType.DataUrl:
            if (!raw.dataurl)
                return null;
            return { type: types_1.FolderIconType.DataUrl, emoji: '', name: '', dataUrl: raw.dataurl };
        default: {
            const exhaustivenessCheck = iconType;
            throw new Error(`Unknown folder icon type: ${exhaustivenessCheck}`);
        }
    }
};
class InteropService_Importer_Md_frontmatter extends InteropService_Importer_Md_1.default {
    async importDirectory(dirPath, parentFolderId) {
        // super.importDirectory() imports files and recursively processes
        // subdirectories. It must run first so that all child folders exist
        // before we try to apply metadata to them.
        await super.importDirectory(dirPath, parentFolderId);
        // The _folder.yml file inside `dirPath` describes the folder that
        // corresponds to `dirPath` itself. In the import flow,
        // `parentFolderId` is the DB ID of that folder (it was created by the
        // caller — either `exec()` for the root, or the parent
        // `importDirectory` for subdirectories).
        await this.applyFolderMetadata(dirPath, parentFolderId);
    }
    async applyFolderMetadata(dirPath, folderId) {
        const metadataPath = `${dirPath}/_folder.yml`;
        if (!(await shim_1.default.fsDriver().exists(metadataPath)))
            return;
        try {
            const content = await shim_1.default.fsDriver().readFile(metadataPath, 'utf-8');
            const metadata = yaml.load(content, { schema: yaml.FAILSAFE_SCHEMA });
            if (!metadata || !metadata.icon)
                return;
            const folderIcon = parseRawYamlToFolderIcon(metadata.icon);
            if (folderIcon) {
                await Folder_1.default.save({ id: folderId, icon: JSON.stringify(folderIcon) }, { isNew: false });
            }
        }
        catch (e) {
            logger.warn(`Failed to import folder metadata from ${metadataPath}:`, e);
        }
    }
    async importFile(filePath, parentFolderId) {
        try {
            const note = await super.importFile(filePath, parentFolderId);
            const { metadata, tags } = (0, frontMatter_1.parse)(note.body);
            const updatedNote = Object.assign(Object.assign(Object.assign({}, note), metadata), { title: metadata.title ? metadata.title : note.title });
            const noteItem = await Note_1.default.save(updatedNote, { isNew: false, autoTimestamp: false });
            const resolvedPath = shim_1.default.fsDriver().resolve(filePath);
            this.importedNotes[resolvedPath] = noteItem;
            for (const tag of tags) {
                await Tag_1.default.addNoteTagByTitle(noteItem.id, tag);
            }
            return noteItem;
        }
        catch (error) {
            error.message = `On ${filePath}: ${error.message}`;
            throw error;
        }
    }
}
exports.default = InteropService_Importer_Md_frontmatter;
//# sourceMappingURL=InteropService_Importer_Md_frontmatter.js.map