/*=========================*/
        #endregion

        #region Service Override Methods
        /*=========================*/

        /// <summary>
        /// Main entry point of the service.
        /// </summary>
        /// <returns></returns>
        protected override ServiceOutcome DoWork()
        {
            // Check if we want to Load historic file.
            if (Instance.ParentInstance.Configuration.Options["File"] != null)
            {
                if (File.Exists(Instance.ParentInstance.Configuration.Options["File"]))
                {
                    return(ServiceOutcome.Success);
                }
            }

            // Initalize FullService with his account access data.
            string accountEmail;

            GetAccountAccessData(out accountEmail);

            AccountData accountData = new AccountData(UserAgent,
                                                      GetConfigurationOptionsField("User"), Encryptor.Decrypt(GetConfigurationOptionsField("Password"), GetConfigurationOptionsField("Password")),
                                                      accountEmail, Token, AppToken);

            FullService fullService = new FullService(accountData);

            fullService.Update();

            // Get data from AdWords and write it to the DB.
            if (!ExecuteJob(fullService))
            {
                return(ServiceOutcome.Failure);
            }

            return(ServiceOutcome.Success);
        }
        private bool SaveReport(FullService fullService, DefinedReportJob googleJob, ref DateTime retrievedDay)
        {
            long   ID;
            string fileName = string.Empty;

            // Get Data from Google AdWords
            ID = fullService.ScheduleReportJob(googleJob, Instance.AccountID);

            // Invaild report.
            if (ID == 0)
            {
                throw new Exception("Can't get data from Google AdWords. return ID from google = 0");
            }

            string url = fullService.GetReportDownloadUrl(ID, Instance.AccountID);

            if (url == "failed")
            {
                throw new Exception("Can't get data from Google AdWords. return Url from google = 'failed'.");
            }

            fileName = WriteResultToFile(url, retrievedDay, googleJob.name, true);

            return(SaveFilePathToDB(_googleServiceType, fileName, retrievedDay, _adwordsFile));
        }
        private void RunReport(FullService fullService, DefinedReportJob googleJob, DateTime retrievedDay, bool errorRun)
        {
            Log.Write(string.Format("Run retriever for service {2}, for account {0}, for date {1}.", Instance.AccountID.ToString(), retrievedDay.ToShortDateString(), Instance.ParentInstance.Configuration.Name), LogMessageType.Information);

            string errorMsg = string.Empty;

            googleJob.startDay = retrievedDay;
            googleJob.endDay   = retrievedDay;

            // Fetch the report from AdWords,
            if (!Retrieve(fullService, googleJob, retrievedDay, ref errorMsg) && !errorRun)
            {
                _errorDates.Add(retrievedDay);
            }
            else if (errorRun)
            {
                Log.Write(string.Format("Can't retreieve date {0}, exception mesaage: {1}", retrievedDay, errorMsg), LogMessageType.Error);
            }
        }
        /// <summary>
        /// Get the data from google AdWords for goolge job.
        /// and save the data into xml file and save a link to the file in the DB.
        /// </summary>
        /// <param name="service"></param>
        /// <param name="googleJob">The job to get his data fro AdWords.</param>
        /// <returns>The name of the xml file that contain the data from AdWords.</returns>
        private bool Retrieve(FullService fullService, DefinedReportJob googleJob, DateTime retrievedDay, ref string errorMsg)
        {
            int  numOfRetries = 0;
            bool reportSaved  = false;

            while (!reportSaved)
            {
                try
                {
                    reportSaved = SaveReport(fullService, googleJob, ref retrievedDay);
                }
                catch (Exception ex)
                {
                    if (numOfRetries >= MaxRetries)                     // too many retries, bail out
                    {
                        errorMsg = ex.Message.ToString();
                        return(false);
                    }

                    ++numOfRetries;
                }
            }
            return(true);
        }
        /*=========================*/
        #endregion

        #region Private Methods
        /*=========================*/

        /// <summary>
        /// Create Google report, Initalize his dats by the Aggergation type.
        /// Get tha data from Google AdWords and insert it to the DB.
        /// </summary>
        /// <param name="fullService">The service that contain the google services
        /// that will be used to fetch the data from Gogle AdWords.</param>
        /// <param name="date">The date to get the data for daily aggergationType.</param>
        /// <param name="aggergationType">daily or summary</param>
        private bool ExecuteJob(FullService fullService)
        {
            DefinedReportJob googleJob;
            DateTime         retrievedDay = DateTime.Now.AddDays(-1);

            // Initalize the report parameters.
            if (Instance.Configuration.Options["ReportType"] == null || Instance.Configuration.Options["ReportType"] != "Content")
            {
                TargetSubDir       = @"Google\Creative\";
                ErrorFilePath      = @"Google\Creative\Errors";
                _googleServiceType = GoogleCreativeServiceType;
                googleJob          = CreateReport("GoogleCreativeReport", DailyAggergation);
            }
            else             // content report
            {
                _googleServiceType = GoogleContentServiceType;
                TargetSubDir       = @"Google\Content\";
                ErrorFilePath      = @"Google\Content\Errors";
                googleJob          = CreateReport("GoogleContentReport", ContetAggergation);
                retrievedDay       = retrievedDay.AddDays(-3);
                string offsetValue = GetConfigurationOptionsField("OffsetDays");
                if (offsetValue != string.Empty)
                {
                    int offset;
                    if (Int32.TryParse(offsetValue, out offset) && offset < 0)
                    {
                        retrievedDay = DateTime.Now.AddDays(offset);
                    }
                }
            }
            ArrayList dates = new ArrayList();

            if (CheckRangeDate(ref dates))
            {
                int i;

                if (dates == null || dates.Count == 0)
                {
                    return(false);
                }
                for (i = 0; i < dates.Count && i < _maxInstancesReRuns; ++i)
                {
                    RunReport(fullService, googleJob, (DateTime)dates[i], false);
                }

                // Write to the log all the dates that din;t eun because max instances ReRuns.
                if (i < dates.Count)
                {
                    string errorMsg = "Can't write the following dates: ";
                    for (int j = i; j < dates.Count; ++j)
                    {
                        errorMsg += ((DateTime)dates[j]).ToShortDateString() + ", ";
                    }

                    errorMsg += " because the service exceed the max instances ReRuns.";
                    Log.Write(errorMsg, LogMessageType.Error);
                }

                if (_errorDates.Count > 0)
                {
                    for (i = 0; i < _errorDates.Count; ++i)
                    {
                        RunReport(fullService, googleJob, (DateTime)dates[i], true);
                    }
                }
            }
            else
            {
                // Check if we need to get manual date.
                //CheckManualDate(ref retrievedDay);
                RunReport(fullService, googleJob, retrievedDay, false);
            }

            return(true);

            #region Obsolete - Time Aggergation

            // Initalize dates acording to aggergation type.
            //if (aggergationType == DailyAggergation) // daily Aggergation
            //{
            //    googleJob.startDay = retrievedDay;
            //    googleJob.endDay = retrievedDay;
            //}
            //else // month Aggergation
            //{
            //    // first day of last month.
            //    googleJob.startDay = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(-1).Month, 1);
            //    // last day of last month.
            //    googleJob.endDay = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(-1).Month,
            //        DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.AddMonths(-1).Month));
            //}

            #endregion
        }