package org.netmelody.cieye.core.observation;

import java.text.SimpleDateFormat;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializer;

public final class CodeBook {

    private final SimpleDateFormat dateFormat;
    private final ImmutableMap<Class<?>, JsonDeserializer<?>> deserialisers;
    private final Function<String, String> munger;

    public CodeBook() {
        this(new SimpleDateFormat());
    }

    public CodeBook(SimpleDateFormat dateFormat) {
        this(dateFormat, Functions.<String>identity(), ImmutableMap.<Class<?>, JsonDeserializer<?>>of());
    }

    private CodeBook(SimpleDateFormat dateFormat, Function<String, String> munger, ImmutableMap<Class<?>, JsonDeserializer<?>> deserialisers) {
        this.dateFormat = dateFormat;
        this.deserialisers = deserialisers;
        this.munger = munger;
    }

    public <T> CodeBook withJsonDeserializerFor(Class<T> type, JsonDeserializer<T> deserialiser) {
        return new CodeBook(this.dateFormat, this.munger, extend(this.deserialisers, type, deserialiser));
    }

    public CodeBook withRawContentMunger(Function<String, String> munger) {
        return new CodeBook(this.dateFormat, Functions.compose(munger, this.munger), this.deserialisers);
    }

    public SimpleDateFormat dateFormat() {
        return dateFormat;
    }

    public Function<String, String> contentMunger() {
        return munger;
    }

    public Map<Class<?>, JsonDeserializer<?>> deserialisers() {
        return this.deserialisers;
    }

    private static <X, Y> ImmutableMap<X, Y> extend(Map<X, Y> map, X key, Y value) {
        return ImmutableMap.<X, Y>builder().putAll(map).put(key, value).build();
    }
}
@@ -272,38 +272,165 @@
 r;%0A%0A
-public final class CodeBook %7B%0A
+import static com.google.common.base.Functions.compose;%0A%0Apublic final class CodeBook %7B%0A%0A    private final String username;%0A    private final String password;
 %0A   
@@ -735,16 +735,24 @@
    this(
+%22%22, %22%22, 
 dateForm
@@ -856,32 +856,66 @@
 rivate CodeBook(
+String username, String password, 
 SimpleDateFormat
@@ -1017,24 +1017,92 @@
 ialisers) %7B%0A
+        this.username = username;%0A        this.password = password;%0A
         this
@@ -1222,12 +1222,8 @@
 blic
- %3CT%3E
  Cod
@@ -1236,75 +1236,44 @@
 with
-JsonDeserializerFor(Class%3CT%3E type, JsonDeserializer%3CT%3E deserialiser
+Credentials(String name, String pass
 ) %7B%0A
@@ -1292,32 +1292,44 @@
 rn new CodeBook(
+name, pass, 
 this.dateFormat,
@@ -1342,23 +1342,16 @@
 munger, 
-extend(
 this.des
@@ -1364,29 +1364,8 @@
 sers
-, type, deserialiser)
 );%0A 
@@ -1483,44 +1483,280 @@
 his.
-dateFormat, Functions.compose(munger
+username, this.password, this.dateFormat, compose(munger, this.munger), this.deserialisers);%0A    %7D%0A%0A    public %3CT%3E CodeBook withJsonDeserializerFor(Class%3CT%3E type, JsonDeserializer%3CT%3E deserialiser) %7B%0A        return new CodeBook(this.username, this.password, this.dateFormat
 , th
@@ -1756,35 +1756,41 @@
 mat, this.munger
-)
 , 
+extend(
 this.deserialise
@@ -1783,33 +1783,180 @@
 is.deserialisers
-)
+, type, deserialiser));%0A    %7D%0A%0A    public String username() %7B%0A        return username;%0A    %7D%0A%0A    public String password() %7B%0A        return password
 ;%0A    %7D%0A%0A    pub

add user/pass to CodeBook