package jp.gr.java_conf.hhayakawa_jp.beehive_client;

import java.util.Arrays;
import java.util.Base64;
import java.util.List;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

// TODO: Beehiveとのセッションタイムアウトを考慮する
class BeehiveContext {

    private BeehiveCredential credential = null;

    static BeehiveContext getBeehiveContext(String user, String password) {
        BeehiveContext context = new BeehiveContext();
        context.credential = login(user, password);
        return context;
    }

    private static BeehiveCredential login(String user, String password) {
        /**
         *  TODO: パスワード誤りなどの認証エラーをケアする
         */
        // header
        // TODO: 入力値のチェック
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        headers.set(HttpHeaders.AUTHORIZATION,
                "Basic " + makeBasicAuthString(user, password));
        HttpEntity<String> entity = new HttpEntity<String>(headers);
        // invoke
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<AntiCsrfToken> result = restTemplate.exchange(
                Constants.BEEHIVE_API_ROOT + "session/login", HttpMethod.POST,
                entity, AntiCsrfToken.class);
        List<String> cookies = result.getHeaders().get("Set-Cookie");
        if (cookies == null || cookies.size() == 0) {
            // TODO: エラー処理
        }
        String session = null;
        for (String cookie : cookies) {
            // TODO: できればCookieオブジェクトにしておきたい
            if (cookie.startsWith("JSESSIONID")) {
                String[] a = cookie.split(";");
                session = a[0];
                break;
            }
        }
        return new BeehiveCredential(session, result.getBody().getToken());
    }

    private static String makeBasicAuthString(String user, String password) {
        String src = user + ":" + password;
        byte[] encoded = Base64.getEncoder().encode(src.getBytes());
        return new String(encoded);
    }

    boolean isActive() {
        // TODO: 実装
        return false;
    }

    BeehiveInvoker getInvoker(BeehiveApiDefinitions api) {
        if (this.credential == null) {
            // TODO: 認証されていない旨のエラー
        }
        switch (api) {
            case INVT_LIST_BYRANGE:
                return new InvtListByRangeInvoker(this.credential);
            case INVT_READ_BATCH:
                return new InvtReadBatchInvoker(this.credential);
            case BKRS_READ_BATCH:
                return new BkrsReadBatchInvoker(this.credential);
            default:
                return null;
        }
    }

}

@@ -713,32 +713,83 @@
 context;%0A    %7D%0A%0A
+    /**%0A     *  TODO: %E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E8%AA%A4%E3%82%8A%E3%81%AA%E3%81%A9%E3%81%AE%E8%AA%8D%E8%A8%BC%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E3%82%B1%E3%82%A2%E3%81%99%E3%82%8B%0A     */%0A
     private stat
@@ -851,27 +851,128 @@
 ) %7B%0A        
-/**
+if (user == null %7C%7C user.length() == 0 %0A                %7C%7C password == null %7C%7C password.length() == 0) %7B
 %0A         * 
@@ -973,49 +973,116 @@
     
-*
   
-TODO: %E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E8%AA%A4%E3%82%8A%E3%81%AA%E3%81%A9%E3%81%AE%E8%AA%8D%E8%A8%BC%E3%82%A8%E3%83%A9%E3%83%BC%E3%82%92%E3%82%B1%E3%82%A2%E3%81%99%E3%82%8B%0A         */
+ throw new NullPointerException(%0A                    %22user name or password is not specified.%22);%0A        %7D
 %0A   

Add input validation of login method.