// Copyright (c) 2015, 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 'dart:collection';

import 'package:string_scanner/string_scanner.dart';

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

/// A single challenge in a WWW-Authenticate header, parsed as per [RFC 2617][].
///
/// [RFC 2617]: http://tools.ietf.org/html/rfc2617
///
/// Each WWW-Authenticate header contains one or more challenges, representing
/// valid ways to authenticate with the server.
class AuthenticationChallenge {
  /// The scheme describing the type of authentication that's required, for
  /// example "basic" or "digest".
  ///
  /// This is normalized to always be lower-case.
  final String scheme;

  /// The parameters describing how to authenticate.
  ///
  /// The semantics of these parameters are scheme-specific. The keys of this
  /// map are case-insensitive.
  final Map<String, String> parameters;

  /// Parses a WWW-Authenticate header, which should contain one or more
  /// challenges.
  ///
  /// Throws a [FormatException] if the header is invalid.
  static List<AuthenticationChallenge> parseHeader(String header) {
    return wrapFormatException("authentication header", header, () {
      var scanner = new StringScanner(header);
      scanner.scan(whitespace);
      var challenges = parseList(scanner, () {
        var scheme = _scanScheme(scanner, whitespaceName: '" " or "="');

        // Manually parse the inner list. We need to do some lookahead to
        // disambiguate between an auth param and another challenge.
        var params = <String, String>{};

        // Consume initial empty values.
        while (scanner.scan(",")) {
          scanner.scan(whitespace);
        }

        _scanAuthParam(scanner, params);

        var beforeComma = scanner.position;
        while (scanner.scan(",")) {
          scanner.scan(whitespace);

          // Empty elements are allowed, but excluded from the results.
          if (scanner.matches(",") || scanner.isDone) continue;

          scanner.expect(token, name: "a token");
          var name = scanner.lastMatch[0];
          scanner.scan(whitespace);

          // If there's no "=", then this is another challenge rather than a
          // parameter for the current challenge.
          if (!scanner.scan('=')) {
            scanner.position = beforeComma;
            break;
          }

          scanner.scan(whitespace);

          if (scanner.scan(token)) {
            params[name] = scanner.lastMatch[0];
          } else {            
            params[name] = expectQuotedString(
                scanner, name: "a token or a quoted string");
          }

          scanner.scan(whitespace);
          beforeComma = scanner.position;
        }

        return new AuthenticationChallenge(scheme, params);
      });

      scanner.expectDone();
      return challenges;
    });
  }

  /// Parses a single WWW-Authenticate challenge value.
  ///
  /// Throws a [FormatException] if the challenge is invalid.
  factory AuthenticationChallenge.parse(String challenge) {
    return wrapFormatException("authentication challenge", challenge, () {
      var scanner = new StringScanner(challenge);
      scanner.scan(whitespace);
      var scheme = _scanScheme(scanner);

      var params = <String, String>{};
      parseList(scanner, () => _scanAuthParam(scanner, params));

      scanner.expectDone();
      return new AuthenticationChallenge(scheme, params);
    });
  }

  /// Scans a single scheme name and asserts that it's followed by a space.
  ///
  /// If [whitespaceName] is passed, it's used as the name for exceptions thrown
  /// due to invalid trailing whitespace.
  static String _scanScheme(StringScanner scanner, {String whitespaceName}) {
    scanner.expect(token, name: "a token");
    var scheme = scanner.lastMatch[0].toLowerCase();

    scanner.scan(whitespace);

    // The spec specifically requires a space between the scheme and its
    // params.
    if (scanner.lastMatch == null || !scanner.lastMatch[0].contains(" ")) {
      scanner.expect(" ", name: whitespaceName);
    }

    return scheme;
  }

  /// Scans a single authentication parameter and stores its result in [params].
  static void _scanAuthParam(StringScanner scanner, Map params) {
    scanner.expect(token, name: "a token");
    var name = scanner.lastMatch[0];
    scanner.scan(whitespace);
    scanner.expect('=');
    scanner.scan(whitespace);

    if (scanner.scan(token)) {
      params[name] = scanner.lastMatch[0];
    } else {            
      params[name] = expectQuotedString(
          scanner, name: "a token or a quoted string");
    }

    scanner.scan(whitespace);
  }

  /// Creates a new challenge value with [scheme] and [parameters].
  AuthenticationChallenge(this.scheme, Map<String, String> parameters)
      : parameters = new UnmodifiableMapView(
            new CaseInsensitiveMap.from(parameters));
}
