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