package org.netmelody.cieye.server.configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.netmelody.cieye.core.domain.Sponsor;
import org.netmelody.cieye.core.observation.KnownOffendersDirectory;

public final class RecordedKnownOffenders implements KnownOffendersDirectory, Refreshable {
    
    private static final Pattern PICTURE_FILENAME_REGEX = Pattern.compile("^\\s*\\[(.*)\\]\\s*$");

    private final Map<String, Sponsor> userMap = new HashMap<String, Sponsor>();
    private final SettingsFile picturesFile;
    
    public RecordedKnownOffenders(SettingsFile picturesFile) {
        this.picturesFile = picturesFile;
        loadPictureSettings();
    }

    @Override
    public void refresh() {
        if (picturesFile.updateAvailable()) {
            loadPictureSettings();
        }
    }
    
    @Override
    public List<Sponsor> search(String fingerprint) {
        final Collection<Sponsor> sponsors = new HashSet<Sponsor>();
        
        final String upperChangeText = fingerprint.toUpperCase();
        for (String keyword : userMap.keySet()) {
            if (upperChangeText.contains(keyword)) {
                sponsors.add(userMap.get(keyword));
            }
        }
        return new ArrayList<Sponsor>(sponsors);
    }
    
    private void loadPictureSettings() {
        userMap.clear();
        extractPicuresFrom(picturesFile.readContent());
    }

    private void extractPicuresFrom(List<String> content) {
        String pictureFilename = "";
        final List<String> aliases = new ArrayList<String>();
        
        for (String line : content) {
            Matcher pictureFilenameMatcher = PICTURE_FILENAME_REGEX.matcher(line);
            if (pictureFilenameMatcher.matches()) {
                if (pictureFilename.length() != 0 && !aliases.isEmpty()) {
                    registerUser(aliases.get(0), "/pictures/" + pictureFilename, aliases.toArray(new String[aliases.size()]));
                }
                pictureFilename = pictureFilenameMatcher.group(1);
                aliases.clear();
                continue;
            }
            
            if (line.trim().length() > 0) {
                aliases.add(line);
            }
        }
        
        if (pictureFilename.length() != 0 && !aliases.isEmpty()) {
            registerUser(aliases.get(0), "/pictures/" + pictureFilename, aliases.toArray(new String[aliases.size()]));
        }
    }
    
    private void registerUser(String name, String pictureUrl, String... keywords) {
        final Sponsor user = new Sponsor(name, pictureUrl);
        userMap.put(name.toUpperCase(), user);
        for (String keyword : keywords) {
            userMap.put(keyword.toUpperCase(), user);
        }
    }
}

@@ -596,16 +596,55 @@
 e final 
+SettingsFile picturesFile;%0A    private 
 Map%3CStri
@@ -702,53 +702,8 @@
 ();%0A
-    private final SettingsFile picturesFile;%0A
     
@@ -1497,33 +1497,18 @@
  userMap
-.clear();%0A      
  
+=
  extract
@@ -1567,20 +1567,43 @@
 private 
-void
+static Map%3CString, Sponsor%3E
  extract
@@ -1650,35 +1650,74 @@
     
-String pictureFilename = %22%22
+final Map%3CString, Sponsor%3E result = new HashMap%3CString, Sponsor%3E()
 ;%0A  
@@ -1772,24 +1772,61 @@
 %3CString%3E();%0A
+        String pictureFilename = %22%22;%0A
         %0A   
@@ -2095,32 +2095,40 @@
    registerUser(
+result, 
 aliases.get(0), 
@@ -2580,16 +2580,24 @@
 terUser(
+result, 
 aliases.
@@ -2684,32 +2684,55 @@
 )%5D));%0A        %7D%0A
+        return result;%0A
     %7D%0A    %0A    p
@@ -2734,24 +2734,31 @@
     private 
+static 
 void registe
@@ -2763,16 +2763,48 @@
 terUser(
+Map%3CString, Sponsor%3E resultMap, 
 String n
@@ -2909,36 +2909,38 @@
 reUrl);%0A        
-user
+result
 Map.put(name.toU
@@ -3012,20 +3012,22 @@
         
-user
+result
 Map.put(

make thread safe