// NOTICE: This file is generated by Rollup. To modify it,
// please instead edit the ESM counterpart and rebuild with Rollup (npm run build).
'use strict';

const node_fs = require('node:fs');
const process = require('node:process');
const node_path = require('node:path');
const createDebug = require('debug');
const fileEntryCache = require('file-entry-cache');
const constants = require('../constants.cjs');
const hash = require('./hash.cjs');
const resolveFilePath = require('./resolveFilePath.cjs');

var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
const debug = createDebug('stylelint:file-cache');

const pkg = JSON.parse(node_fs.readFileSync(new URL('../../package.json', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('lib/utils/FileCache.cjs', document.baseURI).href))), 'utf8'));

class FileCache {
	constructor(
		cacheLocation = constants.DEFAULT_CACHE_LOCATION,
		cacheStrategy = constants.DEFAULT_CACHE_STRATEGY,
		cwd = process.cwd(),
	) {
		if (![constants.CACHE_STRATEGY_METADATA, constants.CACHE_STRATEGY_CONTENT].includes(cacheStrategy)) {
			throw new Error(
				`"${cacheStrategy}" cache strategy is unsupported. Specify either "${constants.CACHE_STRATEGY_METADATA}" or "${constants.CACHE_STRATEGY_CONTENT}"`,
			);
		}

		const cacheFile = node_path.resolve(resolveFilePath(cacheLocation, cwd, `.stylelintcache_${hash(cwd)}`));
		const useCheckSum = cacheStrategy === constants.CACHE_STRATEGY_CONTENT;

		debug(`Cache file is created at ${cacheFile}`);

		try {
			this._fileCache = fileEntryCache.createFromFile(cacheFile, useCheckSum, undefined);
		} catch {
			debug(`Cache file might be corrupt, attempting to remove and recreate the cache file`);

			node_fs.rmSync(cacheFile, { force: true });
			this._fileCache = fileEntryCache.createFromFile(cacheFile, useCheckSum, undefined);
		}

		this._hashOfConfig = '';
		this._useCheckSum = useCheckSum;
	}

	/**
	 * @param {import('stylelint').Config} config
	 */
	calcHashOfConfig(config) {
		if (this._hashOfConfig) return;

		const stylelintVersion = pkg.version;
		const configString = JSON.stringify(config || {});

		this._hashOfConfig = hash(`${stylelintVersion}_${configString}`);
	}

	/**
	 * @param {string} absoluteFilepath
	 * @returns {boolean}
	 */
	hasFileChanged(absoluteFilepath) {
		// Get file descriptor compares current metadata against cached
		// one and stores the result to "changed" prop.w

		/** @type {import('file-entry-cache').FileDescriptorMeta | undefined} */
		const metaCache = this._fileCache.cache.getKey(this._fileCache.createFileKey(absoluteFilepath));
		const descriptor = this._fileCache.getFileDescriptor(absoluteFilepath);

		/** @type {{ hashOfConfig?: string; }} */
		const metadata = (descriptor.meta.data ??= {});

		const configChanged = metadata.hashOfConfig !== this._hashOfConfig;

		let changed;

		if (this._useCheckSum) {
			changed = configChanged || !metaCache?.hash || metaCache.hash !== descriptor.meta.hash;
		} else {
			changed = configChanged || Boolean(descriptor.changed);
		}

		if (!changed) {
			debug(`Skip linting ${absoluteFilepath}. File hasn't changed.`);
		}

		// Mutate file descriptor object and store config hash to each file.
		// Running lint with different config should invalidate the cache.
		if (metadata.hashOfConfig !== this._hashOfConfig) {
			metadata.hashOfConfig = this._hashOfConfig;
		}

		return changed;
	}

	reconcile() {
		this._fileCache.reconcile();
	}

	destroy() {
		this._fileCache.destroy();
	}

	/**
	 * @param {string} absoluteFilepath
	 */
	removeEntry(absoluteFilepath) {
		this._fileCache.removeEntry(absoluteFilepath);
	}
}

module.exports = FileCache;
