/* -*- java -*- */

with ({
  LOG: function LOG(message) {
    dump("header.js: " + message + "\n");
    Components
      .classes['@mozilla.org/consoleservice;1']
      .getService(Components.interfaces.nsIConsoleService)
      .logStringMessage("header.js: " + message);
  }
}) {

  try {
    LOG("start.");

    var getHeaderType = function getHeaderType(header) {
      if(header == null){
        return undefined;
      }
      if(header.scheme != mutualAuth.authScheme.toLowerCase()){
        return undefined;
      }

      if(header.params["algorithm"] != undefined &&
         header.params["validation"] != undefined &&
         header.params["realm"] != undefined &&
         header.params["reason"] != undefined){
        if(header.params["reason"] == "stale-session"){
          return "401-B0-stale";
        } else {
          return "401-B0";
        }
      }

      if(header.params["algorithm"] != undefined &&
         header.params["validation"] != undefined &&
         header.params["user"] != undefined &&
         header.params["realm"] != undefined &&
         header.params["kc1"] != undefined){
        return "req-A1";
      }

      if(header.params["algorithm"] != undefined &&
         header.params["validation"] != undefined &&
         header.params["realm"] != undefined &&
         header.params["sid"] != undefined &&
         header.params["ks1"] != undefined &&
         header.params["nc-max"] != undefined &&
         header.params["nc-window"] != undefined &&
         header.params["time"] != undefined &&
         header.params["path"] != undefined){
        return "401-B1";
      }

      if(header.params["algorithm"] != undefined &&
         header.params["validation"] != undefined &&
         header.params["realm"] != undefined &&
         header.params["sid"] != undefined &&
         header.params["nc"] != undefined &&
         header.params["vkc"] != undefined){
        return "req-A3";
      }

      if(header.params["sid"] != undefined &&
         header.params["vks"] != undefined){
        return "200-B4";
      }

      return undefined;
    };

    var parseHeader = function parseHeader(line) {
      if(typeof(line) != "string"){ return null; }

      var current = 0;
      var limit = line.length;

      var peekChar = function peekChar () {
        if(current == limit){ return null; }
        return line[current];
      };

      var getChar = function getChar () {
        if(current == limit){ return null; }
        return line[current++];
      };

      var isTextChar = function isTextChar(c) {
        var code = c.charCodeAt(0);
        if(32 <= code && code <= 255){
          return code != 127; /* DEL */
        }else{
          return code == 9; /* HT */
        }
      };

      var isCharChar = function isCharChar (c) {
        var code = c.charCodeAt(0);
        if(code < 0 || 127 < code){ return false; }
        return true;
      };

      var isTokenChar = function isTokenChar (c) {
        var code = c.charCodeAt(0);
        if(code <= 31 || 127 <= code){ return false; }
        if(c == "(" || c == ")" || c == "<" || c == ">"  || c == "@" ){ return false; }
        if(c == "," || c == ";" || c == ":" || c == "\\" || c == "\""){ return false; }
        if(c == "/" || c == "[" || c == "]" || c == "?"  || c == "=" ){ return false; }
        if(c == "{" || c == "}" || c == " " || c == "\t"){ return false; }
        return true;
      };

      var skipLWS = function skipLWS () {
        var c;
        while((c = peekChar()) != null){
          if(c == " " || c == "\t"){
            getChar();
          }else{
            break;
          }
        }
      };

      var getToken = function getToken () {
        var token = "", c;
        while((c = peekChar()) != null){
          if(isTokenChar(c)){
            token += getChar();
          }else{
            break;
          }
        }
        return (token.length == 0 ? null : token);
      };

      var getQuotedString = function getQuotedString () {
        if(getChar() != "\""){ return null; }

        var qstring = "";
        while(true){
          var c = getChar();
          if(c == null || isTextChar(c) == false){
            return null;
          }else if(c == "\""){
            break;
          }else if(c == "\\"){
            var n = getChar();
            if(n == null || isCharChar(n) == false){
              return null;
            }else{
              qstring += n;
            }
          }else{
            qstring += c;
          }
        }
        return qstring;
      };

      var ret = {};
      ret.params = {};

      var scheme = getToken();
      if(scheme == null){
        return null;
      }
      ret.scheme = scheme.toLowerCase();

      while(true){
        skipLWS();
        if(peekChar() == null){ break; }

        var key = getToken();
        if(key == null){ return null; }
        if(getChar() != "="){ return null; }

        var value = (peekChar() == "\"" ? getQuotedString() : getToken());
        if(value == null){ return null; }

        ret.params[key.toLowerCase()] = value;

        skipLWS();
        if(peekChar() == null){ break; }
        if(getChar() != ","){ return null; }
      }

      return ret;
    };

  } catch(ex) {
    LOG(ex);
  }
}
