package org.coderepos.nori090;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

public class PeerCastChecker {
    public static final String CH;

    public static final String ADDR;

    public static final boolean debug = false;
    static {
        if ( debug ) {
            CH = "#nnntest";
            ADDR = "irc://irc.media.kyoto-u.ac.jp" + CH;
        }
        else {
            CH = "#[Arekuma]";
            ADDR = "irc://irc.friend.td.nu" + CH;
        }
    }

    public final static String[] YPs =
        { "http://kp.podzone.net/index.txt", "http://extremeyp.ath.cx/index.txt",
            "http://uppeercast.dyndns.org/index.txt", "http://cp.webhop.net/index.txt" };

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

    public void replyPrivmsg( IRCMessage message )
        throws InterruptedException {
        String s = message.getTrailing( DEFAULT_ENCODING );
        IRCNetwork net = message.getNetwork();
        String ch = message.getTarget();
        List<String> list = parse( s );
        if ( list != null ) {
            IRCWriter out = net.writer( DEFAULT_ENCODING );
            for ( String v : list ) {
                NOTICE( out, ch, v );
            }
        }
    }

    private static void NOTICE( IRCWriter writer, String ch, String comment ) {
        writer.format( "NOTICE %s :%s", ch, comment );
        writer.flush();
    }

    private List<String> parse( String s ) {
        if ( s == null ) {
            return null;
        }
        if ( s.startsWith( "check(" ) && s.endsWith( ")" ) ) {
            String reg = s.substring( 6, s.length() - 1 );
            Pattern p = Pattern.compile( reg );
            ArrayList<String> ret = new ArrayList<String>();
            for ( String yp : YPs ) {
                buildComment( getIndexTxtAtProxy( yp ), p, ret );
            }
            if ( ret.isEmpty() ) {
                ret.add( "見当たらないよ！" );
            }
            return ret;
        }
        else if ( s.startsWith( "sure(" ) && s.endsWith( ")" ) ) {
            List<String> l = ContactUrlCollector.searchContactUrl( s.substring( 5, s.length() - 1 ) );
            ArrayList<String> ret = new ArrayList<String>();
            if ( l.isEmpty() ) {
                ret.add( "見当たらないよ！" );
            }
            else {
                for ( String w : l ) {
                    String[] ss = w.split( "<>" );
                    ret.add( ss[0] + " [" + ss[1] + "]" );
                }
            }
            return ret;
        }
        return null;
    }

    private void buildComment( List<String> index_txt, Pattern p, List<String> result ) {
        if ( index_txt == null )
            return;
        for ( String v : index_txt ) {
            Matcher m = p.matcher( v );
            if ( m.find() ) {
                String[] vs = v.split( "<>" );
                StringBuilder sb =
                    new StringBuilder().append( vs[0] ).append( " / " ).append( vs[4] ).append( " / " ).append( vs[5] );
                result.add( sb.toString() );
            }
        }
    }

    public static List<String> getIndexTxtAtProxy( String str_url ) {
        URL url;
        try {
            url = new URL( "http://localhost:8080/" + str_url );
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            BufferedReader br = new BufferedReader( new InputStreamReader( con.getInputStream(), "UTF-8" ) );
            String s = null;
            ArrayList<String> list = new ArrayList<String>();
            while ( ( s = br.readLine() ) != null ) {
                list.add( s );
            }
            return list;
        }
        catch ( MalformedURLException e ) {
            e.printStackTrace();
        }
        catch ( IOException e ) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main( String[] args ) {
        final IRCNetwork net = IRCNetwork.getNetwork( "default" );
        final PeerCastChecker checker = new PeerCastChecker();
        net.addClient( checker );
        String addr = ADDR;
        String nick = "nori_bot";
        String pass = "";
        net.login( addr, nick, pass );
        ContactUrlCollector collector = new ContactUrlCollector();
        ShutdownThread shutdownThread = new ShutdownThread();
        shutdownThread.addListener( collector );
        new Thread( collector ).start();
        Runtime.getRuntime().addShutdownHook( new Thread( shutdownThread ) );
        Thread t = new Thread( new Runnable() {
            ConcurrentHashMap<String, Map<String, String>> m = new ConcurrentHashMap<String, Map<String, String>>();

            @Override
            public void run() {
                try {
                    Thread.sleep( 60000 );
                    IRCWriter out = net.writer( DEFAULT_ENCODING );
                    for ( String yp : YPs ) {
                        Map<String, String> yp_map = search( getIndexTxtAtProxy( yp ) );
                        for ( String k : yp_map.keySet() ) {
                            ConcurrentHashMap<String, String> value = new ConcurrentHashMap<String, String>();
                            value.put( "value", yp_map.get( k ) );
                            value.put( "count", "1" );
                            m.put( k, value );
                            NOTICE( out, CH, "[" + yp_map.get( k ) + "]が配信を始めたよ！" );
                        }
                    }

                    while ( true ) {
                        Thread.sleep( 60000 * 5 );
                        for ( String yp : YPs ) {
                            Map<String, String> yp_map = search( getIndexTxtAtProxy( yp ) );
                            compare( m, yp_map );
                        }
                        searchResult( m, out );
                        clearCount( m );
                    }
                }
                catch ( InterruptedException e ) {
                    e.printStackTrace();
                }
                catch ( Exception e ) {
                    System.err.println( "別スレッドで異常。終了します。" );
                    e.printStackTrace();
                }
            }

            private void clearCount( ConcurrentHashMap<String, Map<String, String>> m2 ) {
                for ( String k : m2.keySet() ) {
                    m2.get( k ).put( "count", "1" );
                }
            }

            private void searchResult( ConcurrentHashMap<String, Map<String, String>> m2, IRCWriter out ) {
                for ( String k : m2.keySet() ) {
                    Map<String, String> m = m2.get( k );
                    String count = m.get( "count" );
                    if ( "0".equals( count ) ) {
                        NOTICE( out, CH, "[" + m.get( "value" ) + "]が配信を始めたよ！" );
                    }
                    else if ( "1".equals( count ) ) {
                        NOTICE( out, CH, "[" + m.get( "value" ) + "]が配信終了したみたい。。。" );
                        m2.remove( k );
                    }
                }
            }

            private void compare( Map<String, Map<String, String>> master, Map<String, String> yp ) {
                for ( String k : yp.keySet() ) {
                    Map<String, String> m = master.get( k );
                    if ( m == null ) {
                        ConcurrentHashMap<String, String> value = new ConcurrentHashMap<String, String>();
                        value.put( "value", yp.get( k ) );
                        value.put( "count", "0" );
                        master.put( k, value );
                    }
                    else {
                        m.put( "count", "2" );
                    }
                }
            }

            private Map<String, String> search( List<String> l ) {
                Pattern p = Pattern.compile( "プログラミング|[Pp]rogramming" );
                ConcurrentHashMap<String, String> user = new ConcurrentHashMap<String, String>();
                if ( l == null )
                    return user;
                for ( String v : l ) {
                    Matcher m = p.matcher( v );
                    if ( m.find() ) {
                        String[] vs = v.split( "<>" );
                        StringBuilder sb =
                            new StringBuilder().append( vs[0] ).append( " / " ).append( vs[4] ).append( " / " ).append(
                                                                                                                        vs[5] );
                        user.put( vs[1], sb.toString() );
                    }
                }
                return user;
            }
        } );
        t.start();
    }
}
