import copy
import csv
import datetime
import json
import mock
import os
import re
import shutil
import tempfile
import urllib

import pyquery

from cStringIO import StringIO
from nose.tools import eq_, ok_, assert_raises
from nose.plugins.skip import SkipTest
from django.test.client import RequestFactory
from django.test.utils import override_settings
from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NA
ME
from django.contrib.auth.models import (
    User,
    AnonymousUser,
    Group,
    Permission
)
from django.core.cache import cache
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse
from django.contrib.contenttypes.models import ContentType

from crashstats.base.tests.testbase import DjangoTestCase
from crashstats.crashstats import models
from crashstats.crashstats.management import PERMISSIONS

from .test_models import Response


SAMPLE_STATUS 
= {
    "breakpad_revision": "1035",
    "hits": [
        {
            "date_oldest_job_queued": "2012-09-28T20:39:33+00:00",
            "date_recently_completed": "2012-09-28T20:40:00+00:00",
            "processors_count": 1,
            "avg_wait_sec": 16.407,
            "waiting_job_count": 56,
            "date_created": "2012-09-28T20:40:02+00:00",
            "id": 410655,
            "avg_process_sec": 0.914149
        },
        {
            "date_oldest_job_queued": "2012-09-28T20:34:33+00:00",
            "date_recently_completed": "2012-09-28T20:35:00+00:00",
            "processors_count": 1,
            "avg_wait_sec": 13.8293,
            "waiting_job_count": 48,
            "date_created": "2012-09-28T20:35:01+00:00",
            "id": 410654,
            "avg_process_sec": 1.24177
        },
        {
            "date_oldest_job_queued": "2012-09-28T20:29:32+00:00",
            "date_recently_completed": "2012-09-28T20:30:01+00:00",
            "processors_count": 1,
            "avg_wait_sec": 14.8803,
            "waiting_job_count": 1,
            "date_created": "2012-09-28T20:30:01+00:00",
            "id": 410653,
            "avg_process_sec": 1.19637
        }
    ],
    "total": 12,
    "socorro_revision": "017d7b3f7042ce76bc80949ae55b41d1e915ab62",
    "schema_revision": "schema_12345"
}

SAMPLE_META = """ {
    "InstallTime": "1339289895",
    "FramePoisonSize": "4096",
    "Theme": "classic/1.0",
    "Version": "5.0a1",
    "Email": "%s",
    "Vendor": "Mozilla",
    "URL": "%s"
} """

SAMPLE_UNREDACTED = """ {
    "client_crash_date": "2012-06-11T06:08:45",
    "dump": "%s",
    "signature": "FakeSignature1",
    "user_comments": "%s",
    "uptime": 14693,
    "release_channel": "nightly",
    "uuid": "11cb72f5-eb28-41e1-a8e4-849982120611",
    "flash_version": "[blank]",
    "hangid": null,
    "distributor_version": null,
    "truncated": true,
    "process_type": null,
    "id": 383569625,
    "os_version": "10.6.8 10K549",
    "version": "5.0a1",
    "build": "20120609030536",
    "ReleaseChannel": "nightly",
    "addons_checked": null,
    "product": "WaterWolf",
    "os_name": "Mac OS X",
    "last_crash": 371342,
    "date_processed": "2012-06-11T06:08:44",
    "cpu_name": "amd64",
    "reason": "EXC_BAD_ACCESS / KERN_INVALID_ADDRESS",
    "address": "0x8",
    "completeddatetime": "2012-06-11T06:08:57",
    "success": true,
    "json_dump": {
      "status": "OK",
      "sensitive": {
        "exploitability": "high"
      },
      "threads": []
    }
} """

BUG_STATUS = """ {
    "hits": [{"id": "222222",
              "signature": "FakeSignature1"},
             {"id": "333333",
              "signature": "FakeSignature1"},
             {"id": "444444",
              "signature": "Other FakeSignature"}
            ]
} """

SAMPLE_SIGNATURE_SUMMARY = {
    "reports": {
        "products": [
            {
                "version_string": "33.0a2",
                "percentage": "57.542",
                "report_count": 103,
                "product_name": "Firefox"
            },
        ],
        "uptime": [
            {
                "category": "< 1 min",
                "percentage": "29.126",
                "report_count": 30
            }
        ],
        "architecture": [
            {
                "category": "x86",
                "percentage": "100.000",
                "report_count": 103
            }
        ],
        "flash_version": [
            {
                "category": "[blank]",
                "percentage": "100.000",
                "report_count": 103
            }
        ],
        "graphics": [
            {
                "report_count": 24,
                "adapter_name": None,
                "vendor_hex": "0x8086",
                "percentage": "23.301",
                "vendor_name": None,
                "adapter_hex": "0x0166"
            }
        ],
        "distinct_install": [
            {
                "crashes": 103,
                "version_string": "33.0a2",
                "product_name": "Firefox",
                "installations": 59
            }
        ],
        "devices": [
            {
                "cpu_abi": "XXX",
                "manufacturer": "YYY",
                "model": "ZZZ",
                "version": "1.2.3",
                "report_count": 52311,
                "percentage": "48.440",
            }
        ],
        "os": [
            {
                "category": "Windows 8.1",
                "percentage": "55.340",
                "report_count": 57
            }
        ],
        "process_type": [
            {
                "category": "Browser",
                "percentage": "100.000",
                "report_count": 103
            }
        ],
        "exploitability": [
            {
                "low_count": 0,
                "high_count": 0,
                "null_count": 0,
                "none_count": 4,
                "report_date": "2014-08-12",
                "medium_count": 0
            }
        ]
    }
}


class RobotsTestViews(DjangoTestCase):

    @override_settings(ENGAGE_ROBOTS=True)
    def test_robots_txt(self):
        url = '/robots.txt'
        response = self.client.get(url)
        eq_(response.status_code, 200)
        eq_(response['Content-Type'], 'text/plain')
        ok_('Allow: /' in response.content)

    @override_settings(ENGAGE_ROBOTS=False)
    def test_robots_txt_disengage(self):
        url = '/robots.txt'
        response = self.client.get(url)
        eq_(response.status_code, 200)
        eq_(response['Content-Type'], 'text/plain')
        ok_('Disallow: /' in response.content)


class FaviconTestViews(DjangoTestCase):

    def test_favicon(self):
        tmp_static_root = tempfile.mkdtemp()
        self.addCleanup(shutil.rmtree, tmp_static_root)

        favicon_dir = os.path.join(tmp_static_root, 'img')
        os.makedirs(favicon_dir)

        favicon_path = os.path.join(favicon_dir, 'favicon.ico')
        with open(favicon_path, 'wb') as icon:
            icon.write('totally fake')

        with self.settings(STATIC_ROOT=tmp_static_root):
            response = self.client.get('/favicon.ico')
            eq_(response.status_code, 200)
            ok_('image/x-icon' in response['Content-Type'])


class BaseTestViews(DjangoTestCase):

    @mock.patch('requests.get')
    def setUp(self, rget):
        super(BaseTestViews, self).setUp()

        # checking settings.CACHES isn't as safe as `cache.__class__`
        if 'LocMemCache' not in cache.__class__.__name__:
            raise ImproperlyConfigured(
                'The tests requires that you use LocMemCache when running'
            )

        # we do this here so that the current/versions thing
        # is cached since that's going to be called later
        # in every view more or less
        def mocked_get(url, params, **options):
            now = datetime.datetime.utcnow()
            yesterday = now - datetime.timedelta(days=1)
            if '/platforms/' in url:
                return Response({
                    "hits": [
                        {
                            'code': 'win',
                            'name': 'Windows',
               