// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library http_parser.media_type;

import 'package:collection/collection.dart';
import 'package:string_scanner/string_scanner.dart';

// All of the following regular expressions come from section 2.2 of the HTTP
// spec: http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html
final _lws = new RegExp(r"(?:\r\n)?[ \t]+");
final _token = new RegExp(r'[^()<>@,;:"\\/[\]?={} \t\x00-\x1F\x7F]+');
final _quotedString = new RegExp(r'"(?:[^"\x00-\x1F\x7F]|\\.)*"');
final _quotedPair = new RegExp(r'\\(.)');

/// A regular expression matching any number of [_lws] productions in a row.
final _whitespace = new RegExp("(?:${_lws.pattern})*");

/// A regular expression matching a character that is not a valid HTTP token.
final _nonToken = new RegExp(r'[()<>@,;:"\\/\[\]?={} \t\x00-\x1F\x7F]');

/// A regular expression matching a character that needs to be backslash-escaped
/// in a quoted string.
final _escapedChar = new RegExp(r'["\x00-\x1F\x7F]');

/// A class representing an HTTP media type, as used in Accept and Content-Type
/// headers.
///
/// This is immutable; new instances can be created based on an old instance by
/// calling [change].
class MediaType {
  /// The primary identifier of the MIME type.
  final String type;

  /// The secondary identifier of the MIME type.
  final String subtype;

  /// The parameters to the media type.
  ///
  /// This map is immutable.
  final Map<String, String> parameters;

  /// The media type's MIME type.
  String get mimeType => "$type/$subtype";

  /// Parses a media type.
  ///
  /// This will throw a FormatError if the media type is invalid.
  factory MediaType.parse(String mediaType) {
    // This parsing is based on sections 3.6 and 3.7 of the HTTP spec:
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html.
    try {
      var scanner = new StringScanner(mediaType);
      scanner.scan(_whitespace);
      scanner.expect(_token);
      var type = scanner.lastMatch[0];
      scanner.expect('/');
      scanner.expect(_token);
      var subtype = scanner.lastMatch[0];
      scanner.scan(_whitespace);

      var parameters = {};
      while (scanner.scan(';')) {
        scanner.scan(_whitespace);
        scanner.expect(_token);
        var attribute = scanner.lastMatch[0];
        scanner.expect('=');

        var value;
        if (scanner.scan(_token)) {
          value = scanner.lastMatch[0];
        } else {
          scanner.expect(_quotedString);
          var quotedString = scanner.lastMatch[0];
          value = quotedString
              .substring(1, quotedString.length - 1)
              .replaceAllMapped(_quotedPair, (match) => match[1]);
        }

        scanner.scan(_whitespace);
        parameters[attribute] = value;
      }

      scanner.expectDone();
      return new MediaType(type, subtype, parameters);
    } on FormatException catch (error) {
      throw new FormatException(
          'Invalid media type "$mediaType": ${error.message}');
    }
  }

  MediaType(this.type, this.subtype, [Map<String, String> parameters])
      : this.parameters = new UnmodifiableMapView(
          parameters == null ? {} : new Map.from(parameters));

  /// Returns a copy of this [MediaType] with some fields altered.
  ///
  /// [type] and [subtype] alter the corresponding fields. [mimeType] is parsed
  /// and alters both the [type] and [subtype] fields; it cannot be passed along
  /// with [type] or [subtype].
  ///
  /// [parameters] overwrites and adds to the corresponding field. If
  /// [clearParameters] is passed, it replaces the corresponding field entirely
  /// instead.
  MediaType change({String type, String subtype, String mimeType,
      Map<String, String> parameters, bool clearParameters: false}) {
    if (mimeType != null) {
      if (type != null) {
        throw new ArgumentError("You may not pass both [type] and [mimeType].");
      } else if (subtype != null) {
        throw new ArgumentError("You may not pass both [subtype] and "
            "[mimeType].");
      }

      var segments = mimeType.split('/');
      if (segments.length != 2) {
        throw new FormatException('Invalid mime type "$mimeType".');
      }

      type = segments[0];
      subtype = segments[1];
    }

    if (type == null) type = this.type;
    if (subtype == null) subtype = this.subtype;
    if (parameters == null) parameters = {};

    if (!clearParameters) {
      var newParameters = parameters;
      parameters = new Map.from(this.parameters);
      parameters.addAll(newParameters);
    }

    return new MediaType(type, subtype, parameters);
  }

  /// Converts the media type to a string.
  ///
  /// This will produce a valid HTTP media type.
  String toString() {
    var buffer = new StringBuffer()
      ..write(type)
      ..write("/")
      ..write(subtype);

    parameters.forEach((attribute, value) {
      buffer.write("; $attribute=");
      if (_nonToken.hasMatch(value)) {
        buffer
          ..write('"')
          ..write(
              value.replaceAllMapped(_escapedChar, (match) => "\\" + match[0]))
          ..write('"');
      } else {
        buffer.write(value);
      }
    });

    return buffer.toString();
  }
}
