//Update LeagueInfo table based on WorldDetails.xml file
        private void UpdateLeagueInfo(HttpClient session, XmlParser parser, ht_stats_dk_dbContext context)
        {
            string leagueData = GetLeagueData(session);

            List <LeagueInfo> leagueList = parser.ParseLeagueInfoData(leagueData);

            Debug.WriteLine("LeagueInfo Count: " + leagueList.Count());

            foreach (LeagueInfo league in leagueList)
            {
                //add or update entity
                if (context.LeagueInfo.Where(c => c.LeagueId == league.LeagueId).Count() == 0) //   Find(league.LeagueId) == null)
                {
                    context.Add(league);
                    Debug.WriteLine("Adding: " + league.LeagueId);
                }
                else
                {
                    context.Update(league);
                }
            }

            try
            {
                context.SaveChanges();
                Debug.WriteLine("Database changes saved!");
            }
            catch (Exception e)
            {
                Debug.WriteLine("DB ERROR: " + e);
            }
        }
        public DbUpdate(int DBUpdateType)
        {
            // create CHPP access, XML parser and Entity framework context
            access     = new ChppAccess();
            parser     = new XmlParser();
            context    = new ht_stats_dk_dbContext(); //Refactor to remove for better performance (see UpdateTeams method).
            eventCodes = GetEventTypes();
            matchTypes = GetMatchTypeList();

            //decide what to update
            switch (DBUpdateType)
            {
            case 1:     //update league_info table
                Debug.WriteLine("Updating league_info table");
                UpdateLeagueInfo(access.session, parser, context);
                break;

            case 2:     //update leauge table
                Debug.WriteLine("Updating league table");
                UpdateLeagues(access.session, parser);
                break;

            case 3:     //update team table
                Debug.WriteLine("Updating team tables");
                UpdateTeams(access.session, parser, context);
                break;

            case 4:     //update match_info
                Debug.WriteLine("Updating tables related to matches");
                UpdateMatchInfo(access.session, parser, context);
                break;

            default:
                Debug.WriteLine("Incorrect update code");
                break;
            }
        }
        //partial update - missing fields: weatherID and added_minutes
        private void UpdateMatchInfo(HttpClient session, XmlParser parser, ht_stats_dk_dbContext context)
        {
            int fetchSeason      = 0;
            int numGoBackSeasons = 1;
            int numTeamsPerRun   = 1;
            int numTeamsTaken    = 0;
            int startAtTeamID    = 237833; //usually 0, but handy if process breaks

            //figure out how many teams' matches to fetch
            int teamCount = (from t in context.Team
                             where t.TeamId > startAtTeamID
                             select t).Count();

            while (numTeamsTaken <= teamCount)
            {
                using (ht_stats_dk_dbContext db = new ht_stats_dk_dbContext())
                {
                    // get a number of teams from team table
                    var data = (from p in db.Team
                                where p.LeagueLevel <= 5 && p.TeamId > startAtTeamID
                                orderby p.TeamId ascending
                                select p).Skip(numTeamsTaken).Take(numTeamsPerRun).ToList();

                    foreach (Team t in data)
                    {
                        //check that team is still in a league level we care about
                        if (t.LeagueLevel <= 5)
                        {
                            //find the active season of the team's league
                            var seasonResult = from t1 in db.Team
                                               join t2 in db.LeagueInfo
                                               on t1.LeagueId equals t2.LeagueId
                                               where t1.TeamId == t.TeamId
                                               select t2.Season;

                            //figure the lastest valid season
                            int i = seasonResult.First() - numGoBackSeasons;
                            while (i < 1)
                            {
                                i++;
                            }
                            fetchSeason = i;
                            Debug.WriteLine("Getting matches for team: " + t.TeamId + ", season: " + fetchSeason);

                            //TODO: Check that season's matches aren't already fetched (add DB field 'earliest season fetched')

                            //get the matches
                            string matchArchive            = GetMatchArchiveData(t.TeamId, fetchSeason, session);
                            IEnumerable <XElement> matches = parser.GetMatchesFromArchive(matchArchive);

                            //parse all the matches for this team in the given season
                            foreach (XElement el in matches)
                            {
                                //check that we are interested in this match
                                if (matchTypes.Contains((int)el.Element("MatchType")))
                                {
                                    //make sure we don't have that match already - slow :-/
                                    if (GetMatchInfo((int)el.Element("MatchID")) == null)
                                    {
                                        //Finally! Add the new match.
                                        db.MatchInfo.Add(parser.ParseMatchInfoData(el));
                                    }
                                }
                            }

                            try //to update the database
                            {
                                db.SaveChanges();
                                //track number of teams processed
                                numTeamsTaken += numTeamsPerRun;
                            }
                            catch (Exception e)
                            {
                                Debug.WriteLine("ERROR SAVING MATCH INFO: " + e.ToString());
                                //TODO: implement proper logging
                            }
                        }
                    }
                    Debug.WriteLine("UPDATED MATCHES FOR " + data.Count() + " TEAMS. " + (teamCount - numTeamsTaken) + " TEAMS LEFT.");
                }
            }
            Debug.WriteLine("Updating match info completed successfully!!");
        }
        //Updates league table based on LeagueDetails.xml file
        private void UpdateLeagues(HttpClient session, XmlParser parser)
        {
            int fetchCounter = 0;
            int fetchBatch   = 0;
            int fetchMax     = 300000;
            int teamID       = 1;


            //TODO: Add USING context ------ UNTESTED!


            //Iterate through all leagues
            for (teamID = 1; teamID <= fetchMax;)   //last max ~270.000
            {
                //fetch in batches to keep db context slim
                for (fetchCounter = 0; fetchCounter <= fetchBatch;)
                {
                    using (ht_stats_dk_dbContext db = new ht_stats_dk_dbContext())
                    {
                        string leagueData = GetLeagueUnitData(teamID, session);
                        //break when no new league is fetched (assumed max reached)
                        if (leagueData == null)
                        {
                            break;
                        }

                        League league = parser.ParseLeagueData(leagueData);

                        //is this league stored already?
                        bool existingLeague = context.League.Where(c => c.SeriesId == league.SeriesId).Count() == 1;


                        if (existingLeague)
                        {
                            context.League.Update(league);
                        }
                        else
                        {
                            context.League.Add(league);
                        }

                        if (fetchCounter >= fetchBatch)
                        {
                            try
                            {
                                context.SaveChanges();
                                Debug.WriteLine("Database changes saved!");
                            }
                            catch (Exception e)
                            {
                                Debug.WriteLine("DB ERROR AT TEAMID " + teamID + ": " + e);
                                break;
                            }
                        }
                        fetchCounter++;
                        teamID++;
                    }
                }
            }
            Debug.WriteLine("Total Leagues Fetched: " + teamID);
        }
        //Update Team table based on TeamDetails.xml
        private void UpdateTeams(HttpClient session, XmlParser parser, ht_stats_dk_dbContext context)
        {
            List <int> teamIDs = new List <int>();
            int        updated = 0;
            int        added   = 0;

            // get a number of series from League table - move to method?
            using (ht_stats_dk_dbContext db = new ht_stats_dk_dbContext())
            {
                var data = (from s in db.League
                            where s.LeagueLevel <= 5
                            orderby s.SeriesId ascending
                            select s).Skip(0).Take(1); //refactor to approach used in UpdateMatchInfo().

                //for every series, get team IDs
                foreach (League l in data)
                {
                    string leagueData = GetLeagueUnitData(l.SeriesId, session);
                    teamIDs.AddRange(parser.ParseTeamIDs(leagueData));
                }
                Debug.WriteLine("Getting data on " + teamIDs.Count + " teams!");
            }

            using (ht_stats_dk_dbContext db = new ht_stats_dk_dbContext())
            {
                //for every team in league, get team data
                foreach (int id in teamIDs)
                {
                    string teamData = GetTeamData(id, session);
                    if (teamData == null)
                    {
                        Debug.WriteLine("no teamdata at team ID: " + id);
                        break;
                    }
                    bool existingTeam = db.Team.Where(c => c.TeamId == id).Count() == 1;
                    //do not store bot teams
                    if (!parser.IsBotTeam(id, teamData))
                    {
                        //add or update team
                        if (!existingTeam)
                        {
                            db.Add(parser.ParseTeamData(id, teamData));  //new team
                            added++;
                            //Debug.WriteLine("Added team: " + id);
                        }
                        else
                        {
                            db.Update(parser.ParseTeamData(id, teamData));  //existing team
                            updated++;
                            //Debug.WriteLine("Updated team: " + id);
                        }
                    }
                    else
                    {
                        if (existingTeam)
                        {
                            //we encountered a bot team in our db
                            //it became bot since first fetch, update to maintain data integrity (matches)
                            db.Update(parser.ParseTeamData(id, teamData));
                            updated++;
                            //Debug.WriteLine("Updated BOT team: " + id);
                        }
                    }
                }
                Debug.WriteLine("Updating " + updated + " teams");
                Debug.WriteLine("Adding " + added + " teams");
                Debug.WriteLine("Skipped " + (teamIDs.Count - updated - added) + " bot teams.");
                try
                {
                    db.SaveChanges();
                    Debug.WriteLine("Database changes saved!");
                }
                catch (Exception e)
                {
                    Debug.WriteLine("DB ERROR: " + e);
                }
            }
        }