//========================================================================
//Copyright 2007-2009 David Yu dyuproject@gmail.com
//------------------------------------------------------------------------
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at 
//http://www.apache.org/licenses/LICENSE-2.0
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//========================================================================

package com.dyuproject.openid;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Same as HtmlBasedDiscvoery but uses regex to search for the openid.server 
 * and openid.delegate
 * 
 * @author David Yu
 * @created May 26, 2009
 */

public class RegexHtmlBasedDiscovery implements Discovery
{
    
    static final Pattern __pattern = Pattern.compile("rel=['\"]openid2?\\.(\\w+)['\"]");
    
    static final HashMap<String,Boolean> __suffixMap = new HashMap<String,Boolean>(6);
    
    private static final String __lookup = "href=";
    
    private static int __bufferSize = Integer.getInteger("rhbd.buffer_size", 2048).intValue();
    
    public static void setBufferSize(int bufferSize)
    {
        __bufferSize = bufferSize;
    }
    
    public static int getBufferSize()
    {
        return __bufferSize;
    }
    
    static
    {
        __suffixMap.put("server", Boolean.TRUE);
        __suffixMap.put("provider", Boolean.TRUE);
        __suffixMap.put("delegate", Boolean.FALSE);
        __suffixMap.put("local_id", Boolean.FALSE);
    }
    
    public OpenIdUser discover(Identifier identifier, OpenIdContext context)
    throws Exception
    {
        return tryDiscover(identifier, context);
    }    

    static OpenIdUser tryDiscover(Identifier identifier, OpenIdContext context)
    throws Exception
    {
        return parse(identifier, new BufferedReader(new InputStreamReader(
                context.getHttpConnector().doGET(identifier.getUrl(), null).getInputStream(), 
                Constants.DEFAULT_ENCODING), __bufferSize));
    }

    static OpenIdUser parse(Identifier identifier, BufferedReader br) throws Exception
    {
        String line = null;
        String openIdServer = null, openIdDelegate = null;
        while((line=br.readLine())!=null)
        {
            Matcher matcher = __pattern.matcher(line);
            boolean parsedServer = false;
            if(matcher.find())
            {
                Boolean isServer = __suffixMap.get(matcher.group(1).trim());
                if(isServer!=null)
                {
                    int idx = line.indexOf(__lookup);
                    if(idx!=-1)
                    {
                        char c = line.charAt(idx+__lookup.length());
                        String value = line.substring(idx+__lookup.length()+1, 
                                line.indexOf(c, idx+__lookup.length()+1)).trim();
                        if(isServer.booleanValue())
                        {
                            openIdServer = value;
                            parsedServer = true;
                            if(openIdDelegate!=null)
                            {
                                new OpenIdUser(identifier.getId(), identifier.getId(), 
                                        openIdServer, openIdDelegate);
                            }
                        }
                        else
                        {
                            openIdDelegate = value;
                            if(openIdServer!=null)
                            {
                                new OpenIdUser(identifier.getId(), identifier.getId(), 
                                        openIdServer, openIdDelegate);
                            }
                        }                        
                    }
                }
            }
            else if(parsedServer)
            {
                // the <link rel='openid.suffix'> tags are expected to be next to each other.
                return new OpenIdUser(identifier.getId(), identifier.getId(), 
                        openIdServer, openIdDelegate);
            }
                
        }
        return openIdServer==null ? null : new OpenIdUser(identifier.getId(), identifier.getId(), 
                openIdServer, openIdDelegate);
    }

}

@@ -3292,38 +3292,20 @@
     
-String value = line.substring(
+int start = 
 idx+
@@ -3323,18 +3323,17 @@
 ngth()+1
-, 
+;
 %0D%0A      
@@ -3354,67 +3354,156 @@
     
-        line.indexOf(c, idx+__lookup.length()+1)).trim();%0D%0A
+String value = line.substring(start, line.indexOf(c, start)).trim();%0D%0A                        if(value.length()!=0)%0D%0A                        %7B%0D%0A    
     
@@ -3567,35 +3567,43 @@
                 
-%7B%0D%0A
+    %7B%0D%0A    
                 
@@ -3665,16 +3665,20 @@
         
+ 
+   
 parsedSe
@@ -3687,24 +3687,28 @@
 er = true;%0D%0A
+    
             
@@ -3769,35 +3769,43 @@
                 
+ 
-%7B%0D%0A
+   %7B%0D%0A    
                 
@@ -3909,32 +3909,36 @@
                 
+    
 openIdServer, op
@@ -3973,32 +3973,36 @@
                 
+    
 %7D%0D%0A             
@@ -4004,35 +4004,43 @@
                 
+ 
-%7D%0D%0A
+   %7D%0D%0A    
                 
@@ -4069,35 +4069,43 @@
                 
+  
+  
 %7B%0D%0A
+    
                 
@@ -4161,32 +4161,36 @@
                 
+  
+  
 if(openIdServer!
@@ -4217,35 +4217,43 @@
                 
-%7B%0D%0A
+    %7B%0D%0A    
                 
@@ -4357,32 +4357,36 @@
                 
+    
 openIdServer, op
@@ -4393,32 +4393,67 @@
 enIdDelegate);%0D%0A
+                                %7D%0D%0A
                 

check for empty string