package org.coderepos.nori090.twitter;

import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import net.unto.twitter.Api;
import net.unto.twitter.Status;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;

import com.mac.tarchan.irc.IRCMessage;
import com.mac.tarchan.irc.IRCNetwork;
import com.mac.tarchan.irc.IRCWriter;

public class TwitterChecker {

    /** debug logger */
    private static Logger log = Logger.getLogger( TwitterChecker.class );

    public static final String CH = "#nnntest";

    public static final String ADDR = "irc://irc.media.kyoto-u.ac.jp" + CH;

    private final static String DEFAULT_ENCODING = "ISO-2022-JP";

    private final IRCNetwork net;

    private final Queue<String> comment = new ConcurrentLinkedQueue<String>();

    public void replyPrivmsg( IRCMessage message )
        throws InterruptedException {
        comment.add( message.getTrailing( DEFAULT_ENCODING ) );
    }

    private static void NOTICE( IRCWriter writer, String ch, String comment ) {
        if ( writer == null ) {
            log.error( "NOTICE write error" );
        }
        else {
            writer.format( IRCWriter.CMD.NOTICE, ch, comment );
            writer.flush();
        }
    }

    String nick = "nori_bot";

    String pass = "";

    public TwitterChecker() {
        super();
        net = IRCNetwork.getNetwork( "ircnet" );
        net.addClient( this );
        String addr = ADDR;
        net.login( addr, nick, pass );
        Thread t = new Thread( this.new Checker(), "TwitterCheckerThread" );
        t.start();
        Thread t2 = new Thread( this.new ConnectionRetry(), "ConnectionRetryThread" );
        t2.start();
    }

    private class ConnectionRetry
        implements Runnable {
        @Override
        public void run() {
            int count = 0;
            try {
                while ( true ) {
                    Thread.sleep( 1000 * 60 );
                    if ( !net.isConnected() ) {
                        if ( count > 10 ) {
                            break;
                        }
                        count++;
                        net.login( ADDR, nick, pass );
                    }
                    else if ( count > 0 ) {
                        // reset
                        count = 0;
                    }
                }
            }
            catch ( Exception e ) {
                e.printStackTrace();
            }
            finally {
                System.err.println( "connection retry err!" );
            }
        }
    }

    private class Checker
        implements Runnable {
        @Override
        public void run() {
            try {
                Properties p = new Properties();
                p.load( TwitterChecker.class.getResourceAsStream( "/net/unto/twitter/user.properties" ) );
                Api api = new Api( p.getProperty( "id" ), p.getProperty( "pass" ) );
                DateTime lastupdate = new DateTime();
                DateTime last = null;
                while ( true ) {
                    Status[] timeline = getTimeline( api );
                    if ( timeline == null ) {
                        Thread.sleep( 60000 * 5 );
                        continue;
                    }
                    IRCWriter out = net.writer( DEFAULT_ENCODING );
                    for ( int i = timeline.length - 1; 0 <= i; i-- ) {
                        Status s = timeline[i];
                        if ( s.getCreatedAt().isAfter( lastupdate ) &&
                            !p.getProperty( "id" ).equals( s.getUser().getScreenName() ) ) {
                            try {
                                NOTICE( out, CH, s.getUser().getScreenName() + " : " +
                                    StringEscapeUtils.unescapeHtml( s.getText() ).replaceAll( "\r|\n", "" ) );
                            }
                            catch ( Exception e ) {
                                System.err.println( "TwitterCheckerThread:IRCへ書き込み失敗" );
                            }
                            last = s.getCreatedAt();
                        }
                    }
                    if ( last != null ) {
                        lastupdate = last;
                    }
                    if ( !comment.isEmpty() ) {
                        try {
                            api.updateStatus( comment.remove() );
                        }
                        catch ( Exception e ) {
                            System.err.println( "TwitterCheckerThread:Twitterへ書き込み失敗" );
                        }
                    }
                    Thread.sleep( 60000 * 3 );
                }
            }
            catch ( Exception e ) {
                System.err.println( "TwitterCheckerThreadで異常。終了します。" );
                e.printStackTrace();
            }
        }

        Status[] getTimeline( Api api ) {
            try {
                return api.getFriendsTimeline();
            }
            catch ( Exception e ) {
                log.error( e.getMessage() );
                return null;
            }
        }
    }
}
