import path from '#path';
import valueParser from 'postcss-value-parser';
import normalize from './normalize.js';

/**
 * A `quote` assignment target for value-parser nodes that aren't otherwise
 * typed: retags the node as a (possibly unquoted) string node.
 * @typedef {{ quote?: string }} QuotedNode
 */

const multiline = /\\[\r\n]/;
// eslint-disable-next-line no-useless-escape
const escapeChars = /([\s\(\)"'])/g;

// Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
// Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/;
// Windows paths like `c:\`
const WINDOWS_PATH_REGEX = /^[a-zA-Z]:\\/;
const dataUrlRegex = /^data:(.*)?,/i;
const extensionRegex = /^.+-extension:\//i;

/**
 * Originally in sindresorhus/is-absolute-url
 *
 * @param {string} url
 */
function isAbsolute(url) {
  if (WINDOWS_PATH_REGEX.test(url)) {
    return false;
  }
  return ABSOLUTE_URL_REGEX.test(url);
}

/**
 * @param {string} url
 * @return {string}
 */
function convert(url) {
  if (isAbsolute(url) || url.startsWith('//')) {
    let normalizedURL;

    try {
      normalizedURL = normalize(url);
    } catch {
      normalizedURL = url;
    }

    return normalizedURL;
  }

  // `path.normalize` always returns backslashes on Windows, need replace in `/`
  return path.normalize(url).replace(new RegExp('\\' + path.sep, 'g'), '/');
}

/**
 * @param {import('postcss').AtRule} rule
 * @return {void}
 */
function transformNamespace(rule) {
  rule.params = valueParser(rule.params)
    .walk((node) => {
      if (
        node.type === 'function' &&
        node.value.toLowerCase() === 'url' &&
        node.nodes.length
      ) {
        /** @type {valueParser.Node} */ (node).type = 'string';
        /** @type {QuotedNode} */ (node).quote =
          node.nodes[0].type === 'string' ? node.nodes[0].quote : '"';
        node.value = node.nodes[0].value;
      }
      if (node.type === 'string') {
        node.value = node.value.trim();
      }
      return false;
    })
    .toString();
}

/**
 * @param {import('postcss').Declaration} decl
 * @return {void}
 */
function transformDecl(decl) {
  decl.value = valueParser(decl.value)
    .walk((node) => {
      if (node.type !== 'function' || node.value.toLowerCase() !== 'url') {
        return false;
      }

      node.before = node.after = '';

      if (!node.nodes.length) {
        return false;
      }
      const url = node.nodes[0];
      let escaped;

      url.value = url.value.trim().replace(multiline, '');

      // Skip empty URLs
      // Empty URL function equals request to current stylesheet where it is declared
      if (url.value.length === 0) {
        /** @type {QuotedNode} */ (url).quote = '';

        return false;
      }

      if (dataUrlRegex.test(url.value)) {
        return false;
      }

      if (!extensionRegex.test(url.value)) {
        url.value = convert(url.value);
      }

      if (escapeChars.test(url.value) && url.type === 'string') {
        escaped = url.value.replace(escapeChars, '\\$1');

        if (escaped.length < url.value.length + 2) {
          url.value = escaped;
          /** @type {valueParser.Node} */ (url).type = 'word';
        }
      } else {
        url.type = 'word';
      }

      return false;
    })
    .toString();
}

/**
 * @return {import('postcss').Plugin}
 */
function pluginCreator() {
  return {
    postcssPlugin: 'postcss-normalize-url',
    /**
     * @param {import('postcss').Root} css
     */
    OnceExit(css) {
      css.walk((node) => {
        if (node.type === 'decl') {
          return transformDecl(node);
        } else if (
          node.type === 'atrule' &&
          node.name.toLowerCase() === 'namespace'
        ) {
          return transformNamespace(node);
        }
      });
    },
  };
}
/** @type {true} */
pluginCreator.postcss = true;
const moduleExports = pluginCreator;

export { moduleExports as default, moduleExports as 'module.exports' };
