import ast
import os.path
import sys
import os
import checkmate.settings as settings
from checkmate.lib.stats.mapreduce import MapReducer
from checkmate.lib.stats.helpers import directory_splitter
import pep8
import tempfile

error_types = {
    'E1' : 'indentation',
    'E2' : 'whitespace',
    'E3' : 'blank line',
    'E4' : 'import',
    'E5' : 'line length',
    'E6' : 'statement',
    'E9' : 'runtime',
    'W1' : 'indentation warning',
    'W2' : 'whitespace warning',
    'W3' : 'blank line warning',
    'W6' : 'deprecation warning',  
}

class Pep8Analyzer():

    def aggregate(self,items):

        stats = {
            'n_warnings' : 0,
            'n_errors' : 0,
        }

        for item in items:
            stats['n_warnings']+=item['n_warnings']
            stats['n_errors']+=item['n_errors']

        return stats

    def analyze(self,content):
        pep8style = pep8.StyleGuide(quiet = True)
        try:
            handle,filename = tempfile.mkstemp()
            fh = os.fdopen(handle,"w")
            fh.write(content)
            fh.close()
            pep8style.init_report(Reporter)
            result = pep8style.check_files([filename])
        finally:
            os.unlink(filename)
        return {'n_warnings' : len([i for i in result.issues if i['level'] == 'warning']),'n_errors':len([i for i in result.issues if i['level'] == 'error'])},result.issues

class Reporter(pep8.BaseReport):
    
    def init_file(self,filename,lines,expected,line_offset):
        pep8.BaseReport.init_file(self,filename,lines,expected,line_offset)

    def error(self,line_number,offset,text,check):

        code = int(text.strip()[1:4])

        if text.strip()[0] == 'E':
            issue_level = 'error'
        else:
            issue_level = 'warning'

        error_code = text.strip()[:2]

        issue = {
            'type' : error_types[error_code] if error_code in error_types else 'unknown',
            'level' : issue_level,
            'description' : text,
            'line_number' : line_number,
            'line_offset' : offset,
            'issue_code' : code,
            'score' : 5 if issue_level == 'warning' else 10,
        }
        self._issues.append(issue)
        pep8.BaseReport.error(self,line_number,offset,text,check)

    @property
    def issues(self):
        return self._issues

    def __init__(self,*args,**kwargs):
        super(Reporter,self).__init__(*args,**kwargs)
        self._issues = []
        self._errors = []
