# -*- coding: utf-8 -*-

#   Copyright 2014 SpendRight, Inc.
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
import re
from logging import getLogger
from os import environ
from os.path import basename
from os.path import exists
from subprocess import CalledProcessError
from subprocess import Popen
from subprocess import PIPE

from bs4 import BeautifulSoup

from srs.scrape import download

SCORE_RE = re.compile(r'^\d+(\.\d)?$')

CAMPAIGN_URL = 'http://www.sourcingnetwork.org/cotton-sourcing-snapshot/'

PDF_URL = 'http://www.sourcingnetwork.org/storage/cotton-publications/Cotton_Sourcing_Snapshot-2015_Addendum.pdf'

# facebook, twitter, and donation URLs are on www.sourcingnetwork.org,
# could scrape
CAMPAIGN = dict(
    author='Responsible Sourcing Network',
    author_url='http://www.sourcingnetwork.org/',
    campaign='Cotton Sourcing Snapshot',
    date='2015',
    donate_url='http://www.sourcingnetwork.org/donate/',
    email='info@sourcingnetwork.org',
    facebook_url='https://www.facebook.com/SourcingNetwork',
    goal='stop forced labor in Uzbekistan',
    # add scale info in anticipation of msd issue #29
    min_score=0,
    max_score=100,
    score_precision=1,
    twitter_handle='@SourcingNetwork',
    url=CAMPAIGN_URL,
)

MAX_SCORE = 100

# based on emailing Patricia Jurewicz <patricia@sourcingnetwork.org>
MIN_GOOD_SCORE = 67
MAX_BAD_SCORE = 33

SYMBOL_TO_CLAIM = {
    '*': dict(
        claim='did not respond to the survey (2nd round)',
        judgment=-1),
    '^': dict(
        claim="signatory to Responsible Sourcing Network's Cotton Pledge",
        judgment=1),
    '+': dict(
        claim='requires suppliers to provide cotton Country of Origin',
        judgment=1),
}
# '#' means 'licensor', which is judgment-free


log = getLogger(__name__)


def scrape_campaign():
    yield 'campaign', CAMPAIGN

    if environ.get('MORPH_COTTON_SNAPSHOT_HTML_PATH'):
        with open(environ.get('MORPH_COTTON_SNAPSHOT_HTML_PATH')) as f:
            html = f.read()
    else:
        html = html_from_pdf()

    soup = BeautifulSoup(html)

    strings = list(soup.body.stripped_strings)

    claim_symbols = set()
    company = None
    score = None

    for s in reversed(strings):
        if SCORE_RE.match(s):
            score = float(s)
            continue

        if len(s) == 1:
            claim_symbols.add(s)
            continue

        if s[:1] in '(#':
            continue

        # reached company name, emit records
        if score is None:
            continue

        company = s

        # fix e.g. "Wil iams-Sonoma" (ligature issue?)
        company = company.replace('l i', 'lli')

        yield 'rating', dict(
            company=company,
            judgment=score_to_judgment(score),
            min_score=CAMPAIGN['min_score'],
            max_score=CAMPAIGN['max_score'],
            score=score)

        for symbol in claim_symbols:
            if symbol in SYMBOL_TO_CLAIM:
                yield 'claim', dict(
                    SYMBOL_TO_CLAIM[symbol],
                    company=company)

        claim_symbols = set()
        company = None
        score = None


def html_from_pdf():
    pdf_path = basename(PDF_URL)
    if not exists(pdf_path):
        log.info('downloading {} -> {}'.format(PDF_URL, pdf_path))
        download(PDF_URL, pdf_path)

    args = ['pdftohtml', '-f', '2', '-l', '2', '-stdout', pdf_path]
    proc = Popen(args, stdout=PIPE)
    stdout, _ = proc.communicate()
    if proc.returncode:
        raise CalledProcessError(proc.returncode, args)

    return stdout


def score_to_judgment(score):
    if score >= MIN_GOOD_SCORE:
        return 1
    elif score <= MAX_BAD_SCORE:
        return -1
    else:
        return 0

@@ -939,16 +939,114 @@
 .%5Cd)?$')
+%0ASYMBOLS_RE = re.compile(r'%5E%5B*%5E+#%5D+$')%0ACOMPANY_AND_SYMBOLS_RE = re.compile(r'%5E(.*?)%5Cs+(%5B*%5E+#%5D+)$')
 %0A%0ACAMPAI
@@ -2501,21 +2501,16 @@
 HOT_HTML
-_PATH
 '):%0A    
@@ -2526,29 +2526,25 @@
 open(environ
-.get(
+%5B
 'MORPH_COTTO
@@ -2562,15 +2562,10 @@
 HTML
-_PATH')
+'%5D
 ) as
@@ -2809,24 +2809,343 @@
 d(strings):%0A
+        # workaround for very old pdftohtml (see #13)%0A        s = s.replace(u'%5Cxa0', u' ')%0A%0A        # fix for All Saints%0A        s = s.replace('l  ', 'll ')%0A%0A        # fix for Williams Sonoma%0A        s = s.replace('l i', 'lli')%0A%0A        if SYMBOLS_RE.match(s):%0A            claim_symbols.update(s)%0A            continue%0A%0A
         if S
@@ -3344,53 +3344,8 @@
 ue%0A%0A
-        # reached company name, emit records%0A
     
@@ -3400,124 +3400,227 @@
     
-company = s%0A%0A        # fix e.g. %22Wil iams-Sonoma%22 (ligature issue?)%0A        company = company.replace('l i', 'lli')%0A
+# reached company name%0A        m = COMPANY_AND_SYMBOLS_RE.match(s)%0A        if m:%0A            company = m.group(1)%0A            claim_symbols.update(m.group(2))%0A        else:%0A            company = s%0A%0A        # emit record
 %0A   

work with htmltopdf 0.12.4 (fixes #13)