// 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 = {};

        // 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 = {};
      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));
}
