// 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.

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

import 'case_insensitive_map.dart';
import 'scan.dart';
import 'utils.dart';

/// 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.
  ///
  /// This is always lowercase. 
  final String type;

  /// The secondary identifier of the MIME type.
  ///
  /// This is always lowercase. 
  final String subtype;

  /// The parameters to the media type.
  ///
  /// This map is immutable and the keys are case-insensitive.
  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.
    return wrapFormatException("media type", mediaType, () {
      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 = <String, String>{};
      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 {
          value = expectQuotedString(scanner);
        }

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

      scanner.expectDone();
      return new MediaType(type, subtype, parameters);
    });
  }

  MediaType(String type, String subtype, [Map<String, String> parameters])
      : type = type.toLowerCase(),
        subtype = subtype.toLowerCase(),
        parameters = new UnmodifiableMapView(
            parameters == null ? {} : new CaseInsensitiveMap.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();
  }
}
