package com.rackspacecloud.blueflood.service.udp;

import com.rackspacecloud.blueflood.service.Configuration;
import com.rackspacecloud.blueflood.types.Locator;
import com.rackspacecloud.blueflood.types.Metric;
import com.rackspacecloud.blueflood.utils.TimeValue;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Test class whose purpose is to hurl random metrics an a UDP ingestion endpoint.
 * I used netty's UDP APIs.  They were cumbersome.  If this is to serve as an example, we might use a simpler way of
 * setting up the sockets.
 */
public class Broadcaster {

    private static final Logger log = LoggerFactory.getLogger(MainIngestor.class);

    private static final TimeValue TTL = new TimeValue(30, TimeUnit.DAYS);
    private static final AtomicInteger counter = new AtomicInteger(0);
    private static final Random rand = new Random(75323);
    
    public void sendHerd(final InetSocketAddress addr, final int numPerSecond) {
        
        final int id = counter.incrementAndGet();
        final Timer timer = new Timer("UDP Broacast Timer " + id);
        final long period = 1000 / numPerSecond;
        final EventLoopGroup group = new NioEventLoopGroup();
        
        // My locator will be tentant_${id},udp_int_metric.
        final Locator locator = Locator.createLocatorFromPathComponents("tenant_" + id, "udp_int_metric");
        log.info("Sending metrics for {} starting {}", locator, System.currentTimeMillis());
        
        try {
            
            // netty UDP boilerplate.
            Bootstrap bootstrap = new Bootstrap()
                    .group(group)
                    .channel(NioDatagramChannel.class)
                    .handler(new SimpleChannelInboundHandler<DatagramPacket>() {
                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
                            System.err.println("SHOULD NOT BE GETTING MESSAGES");
                        }
                    });
            
            final Channel ch = bootstrap.bind(0).sync().channel();
            
            // we'll send the datagrams using a timer.
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    try {
                        ch.writeAndFlush(
                            new DatagramPacket(Unpooled.copiedBuffer(UDPMetricSerialization.toBytes(nextMetrics(locator, rand.nextInt(20) + 1))), addr)
                        ).sync();
                    } catch (Exception ex) {
                        ex.printStackTrace(System.err);
                    }
                }

                @Override
                public boolean cancel() {
                    group.shutdownGracefully();
                    return true;
                }
            };
            
            // set things in motion.
            timer.schedule(task, 0, period);
            
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
            System.exit(-1);
        }
    }
    
    // create a random int metric.
    private static Collection<Metric> nextMetrics(Locator locator, int count) {
        List<Metric> metrics = new ArrayList<Metric>(count);
        for (int i = 0; i < count; i++) {
            metrics.add(new Metric(locator, rand.nextInt(1024), System.currentTimeMillis(), TTL, "gigawatts"));
        }
        log.info("Generating metrics for {} until {}", locator, System.currentTimeMillis());
        return metrics;
    }
    
    // for testing I'm using localhost:2525.
    public static void main(String args[]) {
        try {
            Configuration.init();
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(-1);
            
        }
        
        String host = Configuration.getStringProperty("UDP_BIND_HOST");
        int port = Configuration.getIntegerProperty("UDP_BIND_PORT");
        InetSocketAddress destination = new InetSocketAddress(host, port);
        Broadcaster broadcaster = new Broadcaster();
        
        broadcaster.sendHerd(destination, 1);
    }
}

@@ -88,16 +88,20 @@
 service.
+Core
 Configur
@@ -103,24 +103,24 @@
 figuration;%0A
-
 import com.r
@@ -1543,21 +1543,17 @@
 75323);%0A
-    
 %0A
+
     publ
@@ -1625,25 +1625,17 @@
 cond) %7B%0A
-        
 %0A
+
         
@@ -1850,33 +1850,25 @@
 oopGroup();%0A
-        
 %0A
+
         // M
@@ -2115,25 +2115,17 @@
 lis());%0A
-        
 %0A
+
         
@@ -2130,29 +2130,17 @@
   try %7B%0A
-            
 %0A
+
         
@@ -2673,29 +2673,17 @@
     %7D);%0A
-            
 %0A
+
         
@@ -2741,29 +2741,17 @@
 nnel();%0A
-            
 %0A
+
         
@@ -3484,29 +3484,17 @@
      %7D;%0A
-            
 %0A
+
         
@@ -3567,29 +3567,17 @@
 eriod);%0A
-            
 %0A
+
         
@@ -3686,29 +3686,25 @@
     %7D%0A    %7D%0A
-    
 %0A
+
     // creat
@@ -4154,21 +4154,17 @@
 ;%0A    %7D%0A
-    
 %0A
+
     // f
@@ -4257,211 +4257,53 @@
     
+S
 tr
-y %7B%0A            Configuration.init();%0A        %7D catch (Exception ex) %7B%0A            ex.printStackTrace();%0A            System.exit(-1);%0A            %0A        %7D%0A        %0A        String host = Configuration
+ing host = CoreConfiguration.getInstance()
 .get
@@ -4354,16 +4354,20 @@
  port = 
+Core
 Configur
@@ -4368,24 +4368,38 @@
 nfiguration.
+getInstance().
 getIntegerPr
@@ -4551,24 +4551,16 @@
 ster();%0A
-        
 %0A       

Use new config pattern in blueflood-udp - missed one