import logging
from datetime import datetime
from bs4 import BeautifulSoup, Tag, Comment
from models import NbaTeam, NbaGame, NbaPlayer
from utilities import game_date, sec_played, team_mappings

logger = logging.getLogger()

class HtmlPage:
    def __init__(self, requester, parser):
        self.requester = requester
        self.parser = parser
        self.page_text = None

    def get(self, url):
        """Retrieves web page from url."""
        self.page_text = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

class NbaTeamPage:
    """Nba team page for retrieving, parsing, and persisting team data."""
    def __init__(self, team_id, requester, parser):
        self.url = 'http://sports.yahoo.com/nba/teams/%s/roster/' % team_id
        self.requester = requester
        self.parser = parser
        self.team_id = team_id
        self.player_ids = []
        self.page_text = None

    def get(self, url):
        """Retrieves nba team page from url."""
        self.page_text = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

    def parse_roster(self, soup):
        """Parses nba player ids from an nba team web page."""
        player_ids = []
        roster_rows = soup.find('div', attrs={'class': 'ys-roster-table'}).find('tbody').find_all('tr')

        for row in roster_rows:
            player_id = row.find_all('td')[1].find('a').get('href').split('/')[5]
            player_ids.append(player_id)

        self.player_ids = player_ids
        return player_ids


    def update_roster(self, session, player_ids):
        """Create NbaPlayerPage instances from player ids and persist to session"""
        for player_id in player_ids:
            nba_player = NbaPlayerPage(player_id)
            nba_player.update_player_info(session)

    def update_team(self, session, team_id, player_ids):
        """TODO"""
        nba_team = session.query(NbaTeam).filter(NbaTeam.id == team_id).first()

        if nba_team is None:
            logger.info('\n----------\ncreating new team: true (%s)', self.team_id)
            nba_team = NbaTeam(id=team_id)
        else:
            logger.info('\n----------\ncreating new team: false (%s)', self.team_id)
            nba_team.players = player_ids

        session.add(nba_team)


class NbaPlayerPage:
    """Nba player page for retrieving, parsing, and persisting player data."""
    def __init__(self, player_id, requester, parser):
        self.url = 'http://sports.yahoo.com/nba/players/%s/gamelog/' % player_id
        self.player_id = player_id
        self.requester = requester
        self.parser = parser
        self.page_text = None

    def get(self, url):
        """Retrieves nba player page from url."""
        self.html = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

    def parse_games(self, soup):
        """Parses nba player's game statistics into a table"""
        games = []
        column_names = []
        table = soup.find('table', attrs={'class': 'graph-table'})

        if table is not None:
            rows = table.find('tbody').find_all('tr')
            column_headers = table.find('thead').find_all('tr')[1]

            for row in rows:
                game = []
                cells = row.find_all('td')

                if len(cells) > 1:
                    for cell in cells:
                        game.append(cell.find(text=True))

                games.append(game)
            games.pop()

            for header in column_headers:
                if isinstance(header, Tag):
                    column_names.append(header.text)

        self.games = {
            'columns': column_names,
            'rows': games
        }

        return self.games

    def parse_info_section(self, soup, player_id):
        """Parses nba player's personal information"""
        new_info_section = soup.find('div', attrs={'class': 'ys-player'})
        new_name = new_info_section.find('span', attrs={'class': 'ys-name'}).find(text=True)
        row = new_info_section.find('div', attrs={'class': 'Row'}).find('span')
        num_pos_team = []

        for idx, val in enumerate(row):
            num_pos_team.append(val.find(text=True))

        new_number = num_pos_team[0].split('#')[1].encode('utf-8')
        new_pos = num_pos_team[1].encode('utf-8')
        new_team = team_mappings['city_full_to_abrv'][num_pos_team[2]]
        player_stats = new_info_section.find('div', attrs={'class': 'Fz(13px)'})
        height = 0
        weight = 0

        for section in player_stats:
            key = section.find('span').find(text=True)
            if key == 'Height':
                formatted_height = section.find_all('span')[2].find(text=True)
                split_height = formatted_height.split('\'')
                height = int(split_height[0]) * 12 + int(split_height[1].rstrip('"'))
            if key == 'Weight':
                weight = int(section.find_all('span')[2].find(text=True))

        player_info = {
            'id': player_id,
            'name': new_name,
            'team': new_team,
            'number': new_number,
            'pos': new_pos,
            'height': height,
            'weight': weight,
            'born': datetime(1970, 1, 1, 0, 0)
        }

        return player_info

    def update_player_info(self, player_id, player_info, session, force_update=False):
        """Persists nba player personal information to session"""
        nba_player = session.query(NbaPlayer).filter(NbaPlayer.id == player_id).first()

        if nba_player is None:
            # player doesn't exist
            logger.info('\n----------\ninserting nba player: %s', player_info['name'])
            nba_player = NbaPlayer(player_info)
        else:
            # player exists - update row
            logger.info('\n----------\nupdating nba player: %s', player_info['name'])

            for key, value in player_info.iteritems():
                setattr(nba_player, key, value)

        session.add(nba_player)

    def update_games(self, player_id, player_info, games, session, force_update=False):
        """Persists nba player's game data to session"""
        self.update_player_info(session, force_update)

        for idx, row in enumerate(games['rows']):
            print('IDX: %s', idx)

            if len(row) > 1:
                game_opp = row[1].split('@')
                is_away = True if len(game_opp) > 1 else False

                if row[0] is None:
                    date = datetime(2016, 10, 25, 0, 0)
                else:
                    date = game_date(row[0])

                seconds_played = sec_played(row[3])

                for i, value in enumerate(row):
                    if value == '-':
                        row[i] = '0'

                nba_game = NbaGame(
                    player_id=player_id,
                    game_num=idx,
                    date=date,
                    opp=game_opp.pop(),
                    away=is_away,
                    score=row[2],
                    sec_played=seconds_played,
                    fgm=row[4],
                    fga=row[5],
                    fg_pct=row[6],
                    three_pm=row[7],
                    three_pa=row[8],
                    three_pct=row[9],
                    ftm=row[10],
                    fta=row[11],
                    ft_pct=row[12],
                    off_reb=row[13],
                    def_reb=row[14],
                    total_reb=row[15],
                    ast=row[16],
                    to=row[17],
                    stl=row[18],
                    blk=row[19],
                    pf=row[20],
                    pts=row[21]
                )

                print('checking row')
                print(nba_game.game_num)

                # if session.query(NbaGame).filter(NbaGame.date == nba_game['date']).first() is None:
                if session.query(NbaGame).\
                    filter(NbaGame.game_num == nba_game.game_num).\
                    filter(NbaGame.player_id == nba_game.player_id).\
                    first() is None:

                    logger.info('\n----------\ninserting nba game (%s): true', player_info['name'])
                    session.add(nba_game)
                else:
                    logger.info('\n----------\ninserting nba game (%s): false', player_info['name'])




import logging
from datetime import datetime
from bs4 import BeautifulSoup, Tag, Comment
from models import NbaTeam, NbaGame, NbaPlayer
from utilities import game_date, sec_played, team_mappings

logger = logging.getLogger()

class HtmlPage:
    def __init__(self, requester, parser):
        self.requester = requester
        self.parser = parser
        self.page_text = None

    def get(self, url):
        """Retrieves web page from url."""
        self.page_text = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

class NbaTeamPage:
    """Nba team page for retrieving, parsing, and persisting team data."""
    def __init__(self, team_id, requester, parser):
        self.url = 'http://sports.yahoo.com/nba/teams/%s/roster/' % team_id
        self.requester = requester
        self.parser = parser
        self.team_id = team_id
        self.player_ids = []
        self.page_text = None

    def get(self, url):
        """Retrieves nba team page from url."""
        self.page_text = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

    def parse_roster(self, soup):
        """Parses nba player ids from an nba team web page."""
        player_ids = []
        roster_rows = soup.find('div', attrs={'class': 'ys-roster-table'}).find('tbody').find_all('tr')

        for row in roster_rows:
            player_id = row.find_all('td')[1].find('a').get('href').split('/')[5]
            player_ids.append(player_id)

        self.player_ids = player_ids
        return player_ids


    def update_roster(self, session, player_ids):
        """Create NbaPlayerPage instances from player ids and persist to session"""
        for player_id in player_ids:
            nba_player = NbaPlayerPage(player_id)
            nba_player.update_player_info(session)

    def update_team(self, session, team_id, player_ids):
        """TODO"""
        nba_team = session.query(NbaTeam).filter(NbaTeam.id == team_id).first()

        if nba_team is None:
            logger.info('\n----------\ncreating new team: true (%s)', self.team_id)
            nba_team = NbaTeam(id=team_id)
        else:
            logger.info('\n----------\ncreating new team: false (%s)', self.team_id)
            nba_team.players = player_ids

        session.add(nba_team)


class NbaPlayerPage:
    """Nba player page for retrieving, parsing, and persisting player data."""
    def __init__(self, player_id, requester, parser):
        self.url = 'http://sports.yahoo.com/nba/players/%s/gamelog/' % player_id
        self.player_id = player_id
        self.requester = requester
        self.parser = parser
        self.page_text = None

    def get(self, url):
        """Retrieves nba player page from url."""
        self.html = self.requester.get(url)
        return self.page_text

    def convert(self, text):
        """Converts web page to a searchable entity."""
        self.soup = self.parser.BeautifulSoup(text, 'lxml')
        return self.soup

    def parse_games(self, soup):
        """Parses nba player's game statistics into a table"""
        games = []
        column_names = []
        table = soup.find('table', attrs={'class': 'graph-table'})

        if table is not None:
            rows = table.find('tbody').find_all('tr')
            column_headers = table.find('thead').find_all('tr')[1]

            for row in rows:
                game = []
                cells = row.find_all('td')

                if len(cells) > 1:
                    for cell in cells:
                        game.append(cell.find(text=True))

                games.append(game)
            games.pop()

            for header in column_headers:
                if isinstance(header, Tag):
                    column_names.append(header.text)

        self.games = {
            'columns': column_names,
            'rows': games
        }

        return self.games

    def parse_info_section(self, soup, player_id):
        """Parses nba player's personal information"""
        new_info_section = soup.find('div', attrs={'class': 'ys-player'})
        new_name = new_info_section.find('span', attrs={'class': 'ys-name'}).find(text=True)
        row = new_info_section.find('div', attrs={'class': 'Row'}).find('span')
        num_pos_team = []

        for idx, val in enumerate(row):
            num_pos_team.append(val.find(text=True))

        new_number = num_pos_team[0].split('#')[1].encode('utf-8')
        new_pos = num_pos_team[1].encode('utf-8')
        new_team = team_mappings['city_full_to_abrv'][num_pos_team[2]]
        player_stats = new_info_section.find('div', attrs={'class': 'Fz(13px)'})
        height = 0
        weight = 0

        for section in player_stats:
            key = section.find('span').find(text=True)
            if key == 'Height':
                formatted_height = section.find_all('span')[2].find(text=True)
                split_height = formatted_height.split('\'')
                height = int(split_height[0]) * 12 + int(split_height[1].rstrip('"'))
            if key == 'Weight':
                weight = int(section.find_all('span')[2].find(text=True))

        player_info = {
            'id': player_id,
            'name': new_name,
            'team': new_team,
            'number': new_number,
            'pos': new_pos,
            'height': height,
            'weight': weight,
            'born': datetime(1970, 1, 1, 0, 0)
        }

        return player_info

    def update_player_info(self, player_id, player_info, session, force_update=False):
        """Persists nba player personal information to session"""
        nba_player = session.query(NbaPlayer).filter(NbaPlayer.id == player_id).first()

        if nba_player is None:
            # player doesn't exist
            logger.info('\n----------\ninserting nba player: %s', player_info['name'])
            nba_player = NbaPlayer(player_info)
        else:
            # player exists - update row
            logger.info('\n----------\nupdating nba player: %s', player_info['name'])

            for key, value in player_info.iteritems():
                setattr(nba_player, key, value)

        session.add(nba_player)

    def update_games(self, player_id, player_info, games, session, force_update=False):
        """Persists nba player's game data to session"""
        self.update_player_info(session, force_update)

        for idx, row in enumerate(games['rows']):
            print('IDX: %s', idx)

            if len(row) > 1:
                game_opp = row[1].split('@')
                is_away = True if len(game_opp) > 1 else False

                if row[0] is None:
                    date = datetime(2016, 10, 25, 0, 0)
                else:
                    date = game_date(row[0])

                seconds_played = sec_played(row[3])

                for i, value in enumerate(row):
                    if value == '-':
                        row[i] = '0'

                nba_game = NbaGame(
                    player_id=player_id,
                    game_num=idx,
                    date=date,
                    opp=game_opp.pop(),
                    away=is_away,
                    score=row[2],
                    sec_played=seconds_played,
                    fgm=row[4],
                    fga=row[5],
                    fg_pct=row[6],
                    three_pm=row[7],
                    three_pa=row[8],
                    three_pct=row[9],
                    ftm=row[10],
                    fta=row[11],
                    ft_pct=row[12],
                    off_reb=row[13],
                    def_reb=row[14],
                    total_reb=row[15],
                    ast=row[16],
                    to=row[17],
                    stl=row[18],
                    blk=row[19],
                    pf=row[20],
                    pts=row[21]
                )

                print('checking row')
                print(nba_game.game_num)

                # if session.query(NbaGame).filter(NbaGame.date == nba_game['date']).first() is None:
                if session.query(NbaGame).\
                    filter(NbaGame.game_num == nba_game.game_num).\
                    filter(NbaGame.player_id == nba_game.player_id).\
                    first() is None:

                    logger.info('\n----------\ninserting nba game (%s): true', player_info['name'])
                    session.add(nba_game)
                else:
                    logger.info('\n----------\ninserting nba game (%s): false', player_info['name'])




Retrieves web page from url. Converts web page to a searchable entity. Nba team page for retrieving, parsing, and persisting team data. Retrieves nba team page from url. Converts web page to a searchable entity. Parses nba player ids from an nba team web page. Create NbaPlayerPage instances from player ids and persist to session TODO Nba player page for retrieving, parsing, and persisting player data. Retrieves nba player page from url. Converts web page to a searchable entity. Parses nba player's game statistics into a table Parses nba player's personal information Persists nba player personal information to session # player doesn't exist # player exists - update row Persists nba player's game data to session # if session.query(NbaGame).filter(NbaGame.date == nba_game['date']).first() is None: