<commit_before>﻿/*
 * Emitter.cs
 * 
 * Copyright (c) 2014 Snowplow Analytics Ltd. All rights reserved.
 * This program is licensed to you under the Apache License Version 2.0,
 * and you may not use this file except in compliance with the Apache License
 * Version 2.0. You may obtain a copy of the Apache License Version 2.0 at
 * http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Apache License Version 2.0 is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the Apache License Version 2.0 for the specific
 * language governing permissions and limitations there under.
 * Authors: <NAME>
 * Copyright: Copyright (c) 2014 Snowplow Analytics Ltd
 * License: Apache License Version 2.0
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Net;
using System.Net.NetworkInformation;
using System.Web;
using System.IO;
using System.Web.Script.Serialization;
using System.Windows;

namespace Snowplow.Tracker
{
    public class Emitter : IEmitter, IDisposable
    {
        private string collectorUri;
        private HttpMethod method;
        protected int bufferSize;
        volatile protected List<Dictionary<string, string>> buffer;
        private Action<int> onSuccess;
        private Action<int, List<Dictionary<string, string>>> onFailure = null;
        private bool offlineModeEnabled;
        private MsmqEmitter backupEmitter;
        private Timer flushTimer;
        private bool disposed = false;
        private static JavaScriptSerializer jss = new JavaScriptSerializer();
        private static String noResponseMessage = "Unable to contact server";

        public bool OfflineModeEnabled
        {
            get { return offlineModeEnabled; }
            set { offlineModeEnabled = value;  }
        }

        /// <summary>
        /// Basic emitter to send synchronous HTTP requests
        /// </summary>
        /// <param name="endpoint">Collector domain</param>
        /// <param name="protocol">HttpProtocol.HTTP or HttpProtocol.HTTPS</param>
        /// <param name="port">Port to connect to</param>
        /// <param name="method">HttpMethod.GET or HttpMethod.POST</param>
        /// <param name="bufferSize">Maximum number of events queued before the buffer is flushed automatically.
        /// Defaults to 10 for POST requests and 1 for GET requests.</param>
        /// <param name="onSuccess">Callback executed when every request in a flush has status code 200.
        /// Gets passed the number of events flushed.</param>
        /// <param name="onFailure">Callback executed when not every request in a flush has status code 200.
        /// Gets passed the number of events sent successfully and a list of unsuccessful events.</param>
        /// <param name="offlineModeEnabled">Whether to store unsent requests using MSMQ</param>
        public Emitter(string endpoint, HttpProtocol protocol = HttpProtocol.HTTP, int? port = null, HttpMethod method = HttpMethod.GET, int? bufferSize = null, Action<int> onSuccess = null, Action<int, List<Dictionary<string, string>>> onFailure = null, bool offlineModeEnabled = true)
        {
            collectorUri = GetCollectorUri(endpoint, protocol, port, method);
            this.method = method;
            this.buffer = new List<Dictionary<string, string>>();
            this.bufferSize = Math.Max(1, bufferSize ?? (method == HttpMethod.GET ? 1 : 10));
            this.onSuccess = onSuccess;
            this.onFailure = onFailure;
            this.offlineModeEnabled = offlineModeEnabled;
            Log.Logger.Info(String.Format("{0} initialized with endpoint {1}", this.GetType(), collectorUri));
            if (offlineModeEnabled)
            {
                backupEmitter = new MsmqEmitter(String.Format(".\\private$\\{0}", collectorUri));
                WeakEventManager<NetworkChange, NetworkAvailabilityEventArgs>.AddHandler(null, "NetworkAvailabilityChanged", NetworkAvailabilityChange);
            }
        }

        private static string GetCollectorUri(string endpoint, HttpProtocol protocol, int? port, HttpMethod method)
        {
            string path;
            string requestProtocol = (protocol == HttpProtocol.HTTP) ? "http" : "https";
            if (method == HttpMethod.GET)
            {
                path = "/i";
            }
            else
            {
                path = "/com.snowplowanalytics.snowplow/tp2";
            }
            if (port == null)
            {
                return String.Format("{0}://{1}{2}", requestProtocol, endpoint, path);
            }
            else
            {
                return String.Format("{0}://{1}:{2}{3}", requestProtocol, endpoint, port.ToString(), path);
            }
        }

        /// <summary><commit_msg>Fixed null pointer exception caused by disabling and then enabling offline tracking<commit_after>﻿/*
 * Emitter.cs
 * 
 * Copyright (c) 2014 Snowplow Analytics Ltd. All rights reserved.
 * This program is licensed to you under the Apache License Version 2.0,
 * and you may not use this file except in compliance with the Apache License
 * Version 2.0. You may obtain a copy of the Apache License Version 2.0 at
 * http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Apache License Version 2.0 is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the Apache License Version 2.0 for the specific
 * language governing permissions and limitations there under.
 * Authors: <NAME>
 * Copyright: Copyright (c) 2014 Snowplow Analytics Ltd
 * License: Apache License Version 2.0
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Net;
using System.Net.NetworkInformation;
using System.Web;
using System.IO;
using System.Web.Script.Serialization;
using System.Windows;

namespace Snowplow.Tracker
{
    public class Emitter : IEmitter, IDisposable
    {
        private string collectorUri;
        private HttpMethod method;
        protected int bufferSize;
        volatile protected List<Dictionary<string, string>> buffer;
        private Action<int> onSuccess;
        private Action<int, List<Dictionary<string, string>>> onFailure = null;
        private bool offlineTrackingConfigured = false;
        private bool offlineModeEnabled;
        private MsmqEmitter backupEmitter;
        private Timer flushTimer;
        private bool disposed = false;
        private static JavaScriptSerializer jss = new JavaScriptSerializer();
        private static String noResponseMessage = "Unable to contact server";

        public bool OfflineModeEnabled
        {
            get { return offlineModeEnabled; }
            set
            {
                if (value)
                {
                    configureOfflineTracking();
                }
                offlineModeEnabled = value;
            }
        }

        /// <summary>
        /// Basic emitter to send synchronous HTTP requests
        /// </summary>
        /// <param name="endpoint">Collector domain</param>
        /// <param name="protocol">HttpProtocol.HTTP or HttpProtocol.HTTPS</param>
        /// <param name="port">Port to connect to</param>
        /// <param name="method">HttpMethod.GET or HttpMethod.POST</param>
        /// <param name="bufferSize">Maximum number of events queued before the buffer is flushed automatically.
        /// Defaults to 10 for POST requests and 1 for GET requests.</param>
        /// <param name="onSuccess">Callback executed when every request in a flush has status code 200.
        /// Gets passed the number of events flushed.</param>
        /// <param name="onFailure">Callback executed when not every request in a flush has status code 200.
        /// Gets passed the number of events sent successfully and a list of unsuccessful events.</param>
        /// <param name="offlineModeEnabled">Whether to store unsent requests using MSMQ</param>
        public Emitter(string endpoint, HttpProtocol protocol = HttpProtocol.HTTP, int? port = null, HttpMethod method = HttpMethod.GET, int? bufferSize = null, Action<int> onSuccess = null, Action<int, List<Dictionary<string, string>>> onFailure = null, bool offlineModeEnabled = true)
        {
            collectorUri = GetCollectorUri(endpoint, protocol, port, method);
            this.method = method;
            this.buffer = new List<Dictionary<string, string>>();
            this.bufferSize = Math.Max(1, bufferSize ?? (method == HttpMethod.GET ? 1 : 10));
            this.onSuccess = onSuccess;
            this.onFailure = onFailure;
            this.OfflineModeEnabled = offlineModeEnabled;
            Log.Logger.Info(String.Format("{0} initialized with endpoint {1}", this.GetType(), collectorUri));
        }

        private void configureOfflineTracking()
        {
            if (! offlineTrackingConfigured)
            {
                backupEmitter = new MsmqEmitter(String.Format(".\\private$\\{0}", collectorUri));
                WeakEventManager<NetworkChange, NetworkAvailabilityEventArgs>.AddHandler(null, "NetworkAvailabilityChanged", NetworkAvailabilityChange);
            }
            offlineTrackingConfigured = true;
        }

        private static string GetCollectorUri(string endpoint, HttpProtocol protocol, int? port, HttpMethod method)
        {
            string path;
            string requestProtocol = (protocol == HttpProtocol.HTTP) ? "http" : "https";
            if (method == HttpMethod.GET)
            {
                path = "/i";
            }
            else
            {
                path = "/com.snowplowanalytics.snowplow/tp2";
            }
            if (port == null)
            {
                return String.Format("{0}://{1}{2}", requestProtocol, endpoint, path);
            }
            else
            {
                return String.Format("{0}://{1}:{2}{3}", requestProtocol, endpoint, port.ToString(), path);
            }
        }

        /// <summary>
{'fraction_non_alphanumeric': 0.09580027095026128, 'fraction_numerical': 0.008902651441842461, 'mean_word_length': 2.49746192893401, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1540751', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2486, 'n_words': 866}