package com.insano10;

import com.insano10.BatchingTweetRetriever.TweetBatchCallback;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import twitter4j.Status;
import twitter4j.Twitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.insano10.Location.*;

public class XmasTwitter
{
    private static final int BATCH_SIZE = 10;
    private static final long FREQUENCY = 10L;
    private static final String QUERY_STRING = "christmas";

    public static void main(String[] args)
    {
        final String consumerKey = getSystemProperty("consumerKey");
        final String consumerSecret = getSystemProperty("consumerSecret");

        final Twitter twitterClient = TwitterClientProvider.getTwitterClient(consumerKey, consumerSecret);
        final HttpClient httpClient = HttpClientBuilder.create().build();
        final TweetBatchCallback callback = getTweetBatchCallback(httpClient, "notTheId", "notTheToken");

        createAndStartTweetRetriever(twitterClient, callback, NORTH_LONDON);
        createAndStartTweetRetriever(twitterClient, callback, SOUTH_LONDON);
        createAndStartTweetRetriever(twitterClient, callback, EAST_LONDON);
        createAndStartTweetRetriever(twitterClient, callback, WEST_LONDON);
        createAndStartTweetRetriever(twitterClient, callback, CENTRAL_LONDON);
    }

    private static void createAndStartTweetRetriever(Twitter twitterClient, TweetBatchCallback callback, final Location location)
    {
        final BatchingTweetRetriever tweetRetriever = new BatchingTweetRetriever(twitterClient, callback, QUERY_STRING, location, BATCH_SIZE, FREQUENCY);

        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                tweetRetriever.stop();
            }
        });

        tweetRetriever.start();
    }

    private static String getSystemProperty(final String propertyKey)
    {
        final String propertyValue = System.getProperty(propertyKey);

        if (propertyValue == null)
        {
            throw new RuntimeException(String.format("You must pass in %s to the application in the form of VM arg -D%s=XXX", propertyKey, propertyKey));
        }

        return propertyValue;
    }

    private static TweetBatchCallback getTweetBatchCallback(final HttpClient httpClient, final String deviceId, final String accessToken)
    {
        return (location, tweets) -> {

            tweets.stream().forEach(t ->
            {
                System.out.println(String.format("[%s] - (%s) %d: %s", location.name(), t.getCreatedAt(), t.getId(), t.getText()));
                try
                {
                    final HttpPost postTweets = new HttpPost("https://api.particle.io/v1/devices/" + deviceId + "/tweet");

                    List<NameValuePair> urlParameters = new ArrayList<>();
                    urlParameters.add(new BasicNameValuePair("access_token", accessToken));
                    urlParameters.add(new BasicNameValuePair("args", t.getText()));
                    postTweets.setEntity(new UrlEncodedFormEntity(urlParameters));

                    httpClient.execute(postTweets);
                }
                catch (IOException e)
                {
                    throw new RuntimeException("Failed to send tweets to Photon", e);
                }
            });
        };
    }
}

@@ -392,42 +392,70 @@
 r4j.
-Status;%0Aimport twitter4j.Twitter;%0A
+Twitter;%0A%0Aimport java.io.File;%0Aimport java.io.FileInputStream;
 %0Aimp
@@ -529,16 +529,45 @@
 il.List;
+%0Aimport java.util.Properties;
 %0A%0Aimport
@@ -627,16 +627,97 @@
 itter%0A%7B%0A
+    private static final String PROPERTY_FILE_PATH = %22xmas-twitter.properties%22;%0A%0A
     priv
@@ -904,16 +904,35 @@
 %5B%5D args)
+ throws IOException
 %0A    %7B%0A 
@@ -948,135 +948,64 @@
 nal 
-String consumerKey = getSystemProperty(%22consumerKey%22);%0A        final String consumerSecret = getSystemProperty(%22consumerSecret%22
+Properties properties = getProperties(PROPERTY_FILE_PATH
 );%0A%0A
@@ -1085,21 +1085,71 @@
 ent(
-consumerKey, 
+properties.getProperty(%22consumerKey%22), properties.getProperty(%22
 cons
@@ -1158,16 +1158,18 @@
 erSecret
+%22)
 );%0A     
@@ -1319,34 +1319,82 @@
 nt, 
-%22notTh
+properties.getProperty(%22devic
 eId%22
+)
 , 
-%22notThe
+properties.getProperty(%22access
 Token%22)
+)
 ;%0A%0A 
@@ -2337,32 +2337,32 @@
 tic 
-String getSystem
+Properties get
 Propert
-y
+ies
 (fin
@@ -2383,98 +2383,107 @@
 erty
-Key)%0A    %7B%0A        final String propertyValue = System.getProperty(propertyKey
+FilePath) throws IOException%0A    %7B%0A        final Properties properties = new Properties(
 );%0A
-%0A
         
 if (
@@ -2482,209 +2482,110 @@
     
-if (
 propert
-yValue == null)%0A        %7B%0A            throw new RuntimeException(String.format(%22You must pass in %25s to the application in the form of VM arg -D%25s=XXX%22, propertyKey, propertyKey));%0A        %7D%0A
+ies.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(propertyFilePath));
 %0A   
@@ -2607,14 +2607,11 @@
 pert
-yValue
+ies
 ;%0A  

read inputs from a property file rather than system args