import { VALID_DIGITS } from '../../constants.js'

// The RFC 3966 format for extensions.
const RFC3966_EXTN_PREFIX = ';ext='

/**
 * Helper method for constructing regular expressions for parsing. Creates
 * an expression that captures up to max_length digits.
 * @return {string} RegEx pattern to capture extension digits.
 */
const getExtensionDigitsPattern = (maxLength) => `([${VALID_DIGITS}]{1,${maxLength}})`

/**
 * Helper initialiser method to create the regular-expression pattern to match
 * extensions.
 * Copy-pasted from Google's `libphonenumber`:
 * https://github.com/google/libphonenumber/blob/55b2646ec9393f4d3d6661b9c82ef9e258e8b829/javascript/i18n/phonenumbers/phonenumberutil.js#L759-L766
 * @return {string} RegEx pattern to capture extensions.
 */
export default function createExtensionPattern(purpose) {
	// We cap the maximum length of an extension based on the ambiguity of the way
	// the extension is prefixed. As per ITU, the officially allowed length for
	// extensions is actually 40, but we don't support this since we haven't seen real
	// examples and this introduces many false interpretations as the extension labels
	// are not standardized.
	/** @type {string} */
	var extLimitAfterExplicitLabel = '20';
	/** @type {string} */
	var extLimitAfterLikelyLabel = '15';
	/** @type {string} */
	var extLimitAfterAmbiguousChar = '9';
	/** @type {string} */
	var extLimitWhenNotSure = '6';

	/** @type {string} */
	var possibleSeparatorsBetweenNumberAndExtLabel = "[ \u00A0\\t,]*";
	// Optional full stop (.) or colon, followed by zero or more spaces/tabs/commas.
	/** @type {string} */
	var possibleCharsAfterExtLabel = "[:\\.\uFF0E]?[ \u00A0\\t,-]*";
	/** @type {string} */
	var optionalExtnSuffix = "#?";

	// Here the extension is called out in more explicit way, i.e mentioning it obvious
	// patterns like "ext.".
	/** @type {string} */
	var explicitExtLabels =
	  "(?:e?xt(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45?\uFF58\uFF54\uFF4E?|\u0434\u043E\u0431|anexo)";
	// One-character symbols that can be used to indicate an extension, and less
	// commonly used or more ambiguous extension labels.
	/** @type {string} */
	var ambiguousExtLabels = "(?:[x\uFF58#\uFF03~\uFF5E]|int|\uFF49\uFF4E\uFF54)";
	// When extension is not separated clearly.
	/** @type {string} */
	var ambiguousSeparator = "[- ]+";
	// This is the same as possibleSeparatorsBetweenNumberAndExtLabel, but not matching
	// comma as extension label may have it.
	/** @type {string} */
	var possibleSeparatorsNumberExtLabelNoComma = "[ \u00A0\\t]*";
	// ",," is commonly used for auto dialling the extension when connected. First
	// comma is matched through possibleSeparatorsBetweenNumberAndExtLabel, so we do
	// not repeat it here. Semi-colon works in Iphone and Android also to pop up a
	// button with the extension number following.
	/** @type {string} */
	var autoDiallingAndExtLabelsFound = "(?:,{2}|;)";

	/** @type {string} */
	var rfcExtn = RFC3966_EXTN_PREFIX
	     + getExtensionDigitsPattern(extLimitAfterExplicitLabel);
	/** @type {string} */
	var explicitExtn = possibleSeparatorsBetweenNumberAndExtLabel + explicitExtLabels
	     + possibleCharsAfterExtLabel
	     + getExtensionDigitsPattern(extLimitAfterExplicitLabel)
	     + optionalExtnSuffix;
	/** @type {string} */
	var ambiguousExtn = possibleSeparatorsBetweenNumberAndExtLabel + ambiguousExtLabels
	     + possibleCharsAfterExtLabel
	+ getExtensionDigitsPattern(extLimitAfterAmbiguousChar)
	+ optionalExtnSuffix;
	/** @type {string} */
	var americanStyleExtnWithSuffix = ambiguousSeparator
	+ getExtensionDigitsPattern(extLimitWhenNotSure) + "#";

	/** @type {string} */
	var autoDiallingExtn = possibleSeparatorsNumberExtLabelNoComma
	     + autoDiallingAndExtLabelsFound + possibleCharsAfterExtLabel
	     + getExtensionDigitsPattern(extLimitAfterLikelyLabel)
	+ optionalExtnSuffix;
	/** @type {string} */
	var onlyCommasExtn = possibleSeparatorsNumberExtLabelNoComma
	    + "(?:,)+" + possibleCharsAfterExtLabel
	    + getExtensionDigitsPattern(extLimitAfterAmbiguousChar)
	    + optionalExtnSuffix;

	// The first regular expression covers RFC 3966 format, where the extension is added
	// using ";ext=". The second more generic where extension is mentioned with explicit
	// labels like "ext:". In both the above cases we allow more numbers in extension than
	// any other extension labels. The third one captures when single character extension
	// labels or less commonly used labels are used. In such cases we capture fewer
	// extension digits in order to reduce the chance of falsely interpreting two
	// numbers beside each other as a number + extension. The fourth one covers the
	// special case of American numbers where the extension is written with a hash
	// at the end, such as "- 503#". The fifth one is exclusively for extension
	// autodialling formats which are used when dialling and in this case we accept longer
	// extensions. The last one is more liberal on the number of commas that acts as
	// extension labels, so we have a strict cap on the number of digits in such extensions.
	return rfcExtn + "|"
	       + explicitExtn + "|"
	       + ambiguousExtn + "|"
	       + americanStyleExtnWithSuffix + "|"
	       + autoDiallingExtn + "|"
	       + onlyCommasExtn;
}