/*
 * Copyright 2008 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 org.coderepos.nori090.lib2chj;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.commons.io.IOUtils;

/**
 * @author nori090
 * @version $Rev: 85 $ $Date: 2008-06-02 22:18:54 +0900 (Mon, 02 Jun 2008) $
 */
public class ItaImpl
    implements Ita {

    private HashMap<String, Object> self = new HashMap<String, Object>();

    private LinkedHashMap<String, ThreadData> v1 = new LinkedHashMap<String, ThreadData>();

    private LinkedHashMap<String, ThreadData> v2 = new LinkedHashMap<String, ThreadData>();

    @Override
    public Ita addSubject( Subject subject ) {
        addThreadData( subject );
        return this;
    }

    @Override
    public Ita addThread( Thread thread ) {
        addThreadData( thread );
        return this;
    }

    private void addThreadData( Subject subject ) {
        ThreadData d = v1.get( subject.getId() );
        if ( d == null ) {
            d = v2.get( subject.getTitle() );
        }
        if ( d == null ) {
            d = new ThreadData( subject, null );
        }
        d.setSubject( subject );
        v1.put( subject.getId(), d );
        v2.put( subject.getTitle(), d );
    }

    private void addThreadData( Thread thread ) {
        ThreadData d = v1.get( thread.getId() );
        if ( d == null ) {
            d = v2.get( thread.getTitle() );
        }
        if ( d == null ) {
            d = new ThreadData( null, thread );
        }
        v1.put( thread.getId(), d );
        v2.put( thread.getTitle(), d );
    }

    @Override
    public String getItaName_ja() {
        return (String) self.get( "name_ja" );
    }

    @Override
    public String getItaName() {
        return (String) self.get( "name" );
    }

    @Override
    public Server getServer() {
        return (Server) self.get( "server" );
    }

    @Override
    public Subject getSubject( String thread_key ) {
        ThreadData d = v1.get( thread_key );
        if ( d != null && d.getSubject() != null ) {
            return d.getSubject();
        }
        d = v2.get( thread_key );
        if ( d != null && d.getSubject() != null ) {
            return d.getSubject();
        }
        return null;
    }

    @Override
    public List<Subject> getSubjects() {
        ArrayList<Subject> list = new ArrayList<Subject>();
        for ( ThreadData d : v1.values() ) {
            list.add( d.getSubject() );
        }
        return list;
    }

    @Override
    public List<Subject> getSubjectsFromWeb() {
        String url = getUrl();
        if ( url == null )
            throw new NullPointerException( "url not found" );
        if (!url.endsWith( "/" )) {
            url = url + "/";
        }
        if ( !url.endsWith( "subject.txt" ) ) {
            url = url + "subject.txt";
        }
        HTTP_DATA data = new HTTP_DATA().setUrl( url );
        BufferedReader br = null;
        try {
            br = HttpHelper.http_get( data );
            Date d = new Date();
            if ( br != null ) {
                String line = null;
                while ( ( line = br.readLine() ) != null ) {
                    String[] s = ParseUtil.split_subject( line );
                    String thread_id = s[0].substring( 0, ( s[0].length() - ".dat".length() ) );
                    Subject subject = getSubject( thread_id );
                    if ( subject == null ) {
                        subject = new SubjectImpl();
                    }
                    subject.setIta( this );
                    subject.setLastUpdate( d );
                    subject.setId( thread_id );
                    subject.setTitle( s[1] );
                    subject.setUrl( getUrl() + "subject.txt" );
                    subject.setCommentCount( Integer.parseInt( s[2] ) );
                    Thread thread = getThread( thread_id );
                    if ( thread == null ) {
                        thread = new ThreadImpl();
                    }
                    thread.setIta( this );
                    thread.setId( thread_id );
                    thread.setSubject( subject );
                    thread.setTitle( s[1] );
                    thread.setUrl( getUrl() + "dat/" + s[0] );
                    subject.setThread( thread );
                    addSubject( subject );
                    addThread( thread );
                }
            }
        }
        catch ( IOException e ) {
            e.printStackTrace();
        }
        finally {
            IOUtils.closeQuietly( br );
        }
        return getSubjects();
    }

    @Override
    public Thread getThread( String thread_key ) {
        ThreadData d = v1.get( thread_key );
        if ( d != null && d.getThread() != null ) {
            return d.getThread();
        }
        d = v2.get( thread_key );
        if ( d != null && d.getThread() != null ) {
            return d.getThread();
        }
        return null;
    }

    @Override
    public List<Thread> getThreads() {
        ArrayList<Thread> list = new ArrayList<Thread>();
        for ( ThreadData d : v1.values() ) {
            list.add( d.getThread() );
        }
        return list;
    }

    @Override
    public String getUrl() {
        return (String) self.get( "url" );
    }

    @Override
    public Ita setItaName_ja( String itaName_ja ) {
        self.put( "name_ja", itaName_ja );
        return this;
    }

    @Override
    public Ita setItaName( String itaName ) {
        self.put( "name", itaName );
        return this;
    }

    @Override
    public Ita setSubjects( List<Subject> subjects ) {
        for ( Subject s : subjects ) {
            addSubject( s );
        }
        return this;
    }

    @Override
    public Ita setThreads( List<Thread> threads ) {
        for ( Thread t : threads ) {
            addThread( t );
        }
        return this;
    }

    @Override
    public Ita setUrl( String url ) {
        self.put( "url", url );
        return this;
    }

    class ThreadData {
        private Thread thread;

        private Subject subject;

        public ThreadData( Subject subject, Thread thread ) {
            super();
            this.thread = thread;
            this.subject = subject;
        }

        public Thread getThread() {
            return thread;
        }

        public ThreadData setThread( Thread thread ) {
            this.thread = thread;
            return this;
        }

        public Subject getSubject() {
            return subject;
        }

        public ThreadData setSubject( Subject subject ) {
            this.subject = subject;
            return this;
        }
    }
}
