“use strict”;

const tokenRegexp = /^[!#$%&'*+-.^_`|~0-9A-Za-z]+$/; const contentTypeRegexp = /^(.*?)/(.*?)([t ]*;.*)?$/; const parameterValueRegexp = /^(.*?)=(.*)$/; const quotedStringRegexp = /“(?:[t x21x23-x5Bx5D-x7Ex80-xFF]|(?:\[t x21-x7Ex80-xFF]))*”/; const qescRegExp = /\([t x21-x7Ex80-xFF])/g; const quoteRegExp = /([\“])/g;

function qstring(val) {

if (tokenRegexp.test(val)) {
  return val;
}
return "\"" + val.replace(quoteRegExp, "\\$1") + "\"";

}

class ContentType {

constructor(type, subtype, parameterList) {
  this.type = type;
  this.subtype = subtype;
  this.parameterList = parameterList;
}
get(key) {
  key = String(key).toLowerCase();

  const param = this.parameterList.reverse().find(v => v.key === key);
  return param ? param.value : undefined;
}
set(key, value) {
  key = String(key).toLowerCase();
  value = String(value);

  this.parameterList = this.parameterList.filter(v => v.key !== key);
  this.parameterList.push({
    separator: ";",
    key,
    value
  });
}
isXML() {
  return (this.subtype === "xml" && (this.type === "text" || this.type === "application")) ||
         this.subtype.endsWith("+xml");
}
isHTML() {
  return this.subtype === "html" && this.type === "text";
}
isText() {
  return this.type === "text";
}
toString() {
  return this.type + "/" + this.subtype +
    this.parameterList.map(v => v.separator + (v.key ? v.key + "=" + qstring(v.value) : v.value))
    .join("");
}

}

module.exports = function parseContentType(contentType) {

if (!contentType) {
  return null;
}
const contentTypeMatch = contentTypeRegexp.exec(contentType);
if (contentTypeMatch) {
  const type = contentTypeMatch[1];
  const subtype = contentTypeMatch[2];
  const parameters = contentTypeMatch[3];
  if (tokenRegexp.test(type) && tokenRegexp.test(subtype)) {
    const parameterPattern = /([\t ]*;[\t ]*)([^\t ;]*)/g;
    const parameterList = [];
    let match;
    while ((match = parameterPattern.exec(parameters))) {
      const separator = match[1];
      const keyValue = parameterValueRegexp.exec(match[2]);
      let key;
      let value;
      if (keyValue && tokenRegexp.test(keyValue[1])) {
        key = keyValue[1];
        if (quotedStringRegexp.test(keyValue[2])) {
          value = keyValue[2]
            .substr(1, keyValue[2].length - 2)
            .replace(qescRegExp, "$1");
        } else {
          value = keyValue[2];
        }
      }
      if (key) {
        parameterList.push({
          separator,
          key: key.toLowerCase(),
          value
        });
      } else {
        parameterList.push({
          separator,
          value: match[2]
        });
      }
    }
    return new ContentType(type.toLowerCase(), subtype.toLowerCase(), parameterList);
  }
  return null;
}
return null;

};