/*
 * Copyright 2007 nori090
 *
 * 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 lib2chj.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import lib2chj.struct.Comment;
import lib2chj.struct.HTTP_DATA;
import lib2chj.struct.Ita;
import lib2chj.struct.Server;
import lib2chj.struct.Subject;
import lib2chj.struct.Thread;

/**
 * 2chのスレッドを構造体に押し込む仕事
 * 
 * @author nori090
 * @version $Rev: 19 $ $Date: 2008-03-25 22:46:11 +0900 (Tue, 25 Mar 2008) $
 */
public class ThreadBuilder {
    Map<String, Server> server_map;

    public ThreadBuilder( Map<String, Server> m ) {
        super();
        if ( m == null )
            throw new NullPointerException( "map is null !" );
        this.server_map = m;
    }

    public ThreadBuilder() {
        super();
        this.server_map = new HashMap<String, Server>();
    }

    public ThreadBuilder get( String url )
        throws IOException {
        Thread thread = _init( url );
        HTTP_DATA data = thread.getHttpData();
        BufferedReader br = HttpHelper.http_get_for_dat( data );
        if ( br != null ) {
            String line = null;
            while ( null != ( line = br.readLine() ) ) {
                String[] comme = ParseUtil.split_comment( line );
                if ( comme.length == 5 && StringUtils.isBlank( thread.getTitle() ) ) {
                    thread.setTitle( comme[4] );
                }
                Comment comment = new Comment( thread );
                comment.setName( comme[0] );
                comment.setMailto( comme[1] );
                String[] date_id = ParseUtil.split_date_id( comme[2] );
                if ( date_id.length == 2 ) {
                    comment.setId( date_id[1] );
                }
                comment.setDate( date_id[0] );
                comment.setBody( comme[3] );
                if ( thread.getComments() == null ) {
                    thread.setComments( new ArrayList<Comment>() );
                }
                comment.setNum( thread.getComments().size() + 1 );
                thread.addComment( comment );
            }
            thread.getSubject().setCommentCount( thread.getComments().size() );
            br.close();
        }
        return this;
    }

    /**
     * 初期化処理です。基本的に設定されていなければ設定する流れ。
     */
    Thread _init( String u ) {
        URL url = null;
        try {
            url = new URL( u );
        }
        catch ( MalformedURLException e ) {
            e.printStackTrace();
            throw new RuntimeException( e );
        }
        Server serv = server_map.get( url.getHost() );
        if ( serv == null )
            serv = new Server();
        serv.setServerName( url.getHost() );
        server_map.put( serv.getServerName(), serv );
        String ita_name = HttpHelper._split_ita_name_at_path( url.getPath() );
        if ( ita_name == null )
            throw new RuntimeException( "unknown ita name" );
        if ( serv.getItaMap() == null ) {
            serv.setItaMap( new HashMap<String, Ita>() );
        }
        /*
         * subject.txtは、http getしたときに、一応、更新順序で並んでいるみたいなので、 LinkedHashMapとしてみる。（列挙するときに順序を持たせる）
         */
        if ( serv.getIta( ita_name ) == null ) {
            Ita ita = new Ita( serv );
            ita.setItaName( ita_name );
            ita.setUrl( url.getProtocol() + "://" + url.getHost() + "/" + ita_name );
            ita.setSubjects( new LinkedHashMap<String, Subject>() );
            ita.setThreads( new LinkedHashMap<String, Thread>() );
            serv.putIta( ita );
        }
        String thread_id = HttpHelper._split_thread_id_at_path( url.getPath() );
        if ( thread_id == null )
            throw new RuntimeException( "unknown thread id" );
        Ita ita = serv.getIta( ita_name );
        Subject subject = ita.getSubject( thread_id );
        Thread thread = ita.getThread( thread_id );
        if ( null == subject ) {
            subject = new Subject( ita );
            subject.setUrl( ita.getUrl() + "/subject.txt" );
            subject.setId( thread_id );
        }
        if ( null == thread ) {
            thread = new Thread( ita );
            thread.setUrl( u );
            thread.setHttpData( new HTTP_DATA().setUrl( u ) );
            thread.setId( thread_id );
            thread.setSubject( subject );
        }
        subject.setThread( thread );
        ita.putSubject( subject );
        ita.putThread( thread );
        return thread;
    }

    public Map<String, Server> toMap() {
        return server_map;
    }
}
