/*
 * HeadsUp Agile
 * Copyright 2009-2012 Heads Up Development Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.headsupdev.agile.security;

import org.headsupdev.agile.api.Manager;
import org.headsupdev.agile.api.User;
import org.headsupdev.support.java.Base64;

import java.util.HashMap;
import java.util.Map;

/**
 * A login manager class that handles remembering users on the system
 * <p/>
 * Created: 02/02/2013
 *
 * @author Andrew Williams
 * @since 2.0
 */
public abstract class RememberedLoginManager
{
    private static final String REMEMBER_STORE_KEY = "remembermes";

    private static Map<String, String> rememberMap = null;

    public User getRememberedUser( String context )
    {
        checkRemembers();

        int pos = context.indexOf( ':' );
        if ( pos != -1 ) {
            String username = context.substring( 0, pos );
            String key = context.substring( pos + 1 );

            if ( key.equals( rememberMap.get( username ) ) ) {
                return Manager.getSecurityInstance().getUserByUsername( username );
            }
        }

        return null;
    }

    public void rememberUser( User user, String random )
    {
        checkRemembers();
        rememberMap.put( user.getUsername(), random );
        saveRemembers();
    }

    public void forgetUser( User user )
    {
        checkRemembers();
        rememberMap.remove( user.getUsername() );
        saveRemembers();
    }

    private void checkRemembers()
    {
        if ( rememberMap != null )
        {
            return;
        }

        rememberMap = new HashMap<String,String>();
        String data = Manager.getStorageInstance().getGlobalConfiguration().getProperty( REMEMBER_STORE_KEY );
        if ( data == null ) {
            return;
        }
        data = new String( Base64.decodeBase64( data.getBytes() ) );

        String[] entries = data.split( ";" );
        for ( String entry : entries )
        {
            String[] parts = entry.split( ":" );
            if ( parts.length < 2 )
            {
                continue;
            }

            rememberMap.put( parts[0], parts[1] );
        }
    }

    private void saveRemembers()
    {
        if ( rememberMap == null )
        {
            return;
        }

        StringBuilder buffer = new StringBuilder();
        for ( String user : rememberMap.keySet() )
        {
            buffer.append( user );
            buffer.append( ":" );
            buffer.append( rememberMap.get( user ) );
            buffer.append( ";" );
        }
        String data = buffer.toString();
        if ( buffer.length() > 0 )
        {
            data = data.substring( 0, buffer.length() - 1 );
        }

        data = new String( Base64.encodeBase64( data.getBytes() ) );
        Manager.getStorageInstance().getGlobalConfiguration().setProperty( REMEMBER_STORE_KEY, data );
    }
}

@@ -921,37 +921,9 @@
 til.
-HashMap;%0Aimport java.util.Map
+*
 ;%0A%0A/
@@ -1221,23 +1221,28 @@
 String, 
+Set%3C
 String%3E
+%3E
  remembe
@@ -1540,24 +1540,31 @@
     
-if ( key.equals(
+Set%3CString%3E remembers =
  rem
@@ -1587,16 +1587,79 @@
 ername )
+;%0A            if ( remembers != null && remembers.contains( key
  ) ) %7B%0A 
@@ -1875,32 +1875,234 @@
 eckRemembers();%0A
+        Set%3CString%3E remembers = rememberMap.get(user.getUsername());%0A        if ( remembers == null )%0A        %7B%0A            remembers = new HashSet%3CString%3E();%0A        %7D%0A        remembers.add( random );%0A
         remember
@@ -2131,21 +2131,24 @@
 ame(), r
-andom
+emembers
  );%0A    
@@ -2486,23 +2486,28 @@
 %3CString,
+Set%3C
 String%3E
+%3E
 ();%0A    
@@ -3016,16 +3016,31 @@
 arts%5B0%5D,
+ setFromString(
  parts%5B1
@@ -3040,16 +3040,18 @@
 parts%5B1%5D
+ )
  );%0A    
@@ -3386,16 +3386,31 @@
 .append(
+ stringFromSet(
  remembe
@@ -3425,16 +3425,18 @@
 ( user )
+ )
  );%0A    
@@ -3698,24 +3698,24 @@
 ytes() ) );%0A
-
         Mana
@@ -3810,11 +3810,768 @@
 );%0A    %7D
+%0A%0A    private String stringFromSet( Set%3CString%3E set )%0A    %7B%0A        StringBuilder builder = new StringBuilder();%0A%0A        if ( set == null %7C%7C set.size() == 0 )%0A        %7B%0A            return %22%22;%0A        %7D%0A%0A        for ( String string : set )%0A        %7B%0A            builder.append( string );%0A            builder.append( %22,%22 );%0A        %7D%0A%0A        String ret = builder.toString();%0A        return ret.substring( 0, ret.length() - 1 );%0A    %7D%0A%0A    private Set%3CString%3E setFromString( String input )%0A    %7B%0A        Set%3CString%3E ret = new HashSet%3CString%3E();%0A        if ( input == null %7C%7C input.length() == 0 )%0A        %7B%0A            return ret;%0A        %7D%0A%0A        String%5B%5D split = input.split( %22,%22 );%0A        ret.addAll( Arrays.asList( split ) );%0A        return ret;%0A    %7D
 %0A%7D%0A

Allow many remember me cookies for the same account