#! /bin/env python
# -*- coding: utf-8 -*-

# Use when Calisphere Object URLs for a collection change, to generate
# a redirect file mapping 'old' (on SOLR-PROD) to 'new' (on SOLR-TEST) URLs.
#
# This script takes the JSON file generated by
# external-redirect-get-solr_prod-id.py as input and queries SOLR-TEST to find
# matching records according to the 'match field' entered in
# external-redirect-get-solr_prod-id.py. It then generates a CSV file with a
# line for each match found, pairing the 'old' SOLR-PROD URLs with the
# corresponding 'new' SOLR-TEST URLs

import os
import argparse
import json
import requests
import solr
import ssl

ssl._create_default_https_context = ssl._create_unverified_context

# to get rid of ssl key warning
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

# need to hardcode in SOLR-STAGE
SOLR_URL = "https://harvest-stg.cdlib.org/solr_api/"
SOLR_API_KEY = os.environ.get('SOLR_API_KEY', '')

def get_test_id(fullQuery, matchField, prod_id, matchVal, cid, exact_match):
    solr_auth = { 'X-Authentication-Token': SOLR_API_KEY } if SOLR_API_KEY else None
    if exact_match:
        fullQuery = fullQuery.replace('*','"')
    query = { 'q': fullQuery, 'rows':10, 'fl': 'id,{}'.format(matchField)}
    solr_endpoint = SOLR_URL + 'query'
    resp_obj =  requests.get(solr_endpoint,
                                    headers=solr_auth,
                                    params=query,
                                    verify=False)
    results = resp_obj.json()
    if results["response"]["numFound"] > 0:
        if exact_match is True:
            if results["response"]["numFound"] > 1:
                matchVal = matchVal.replace("\ ","+")
                new_id = '/collections/{}/?rq={}:"{}"'.format(cid,matchField,matchVal)
            else:
                for rec in results["response"]["docs"]:
                    found_id = rec["id"]
                    new_id = '/item/{}/'.format(found_id)
                    break
        else:
            for rec in results["response"]["docs"]:
                found_id = rec["id"]
                new_id = '/item/{}/'.format(found_id)
                break
        return prod_id,new_id
    else:
        new_id = "NOT FOUND"
        return prod_id,new_id

def main(inFile, exact_match):
    f = open(inFile, "r")
    reCount = 0
    try:
        contents = json.load(f)
        matchField = contents["responseHeader"]["params"]["fl"].split(',')[1]
        queryVal = contents["responseHeader"]["params"]["q"].replace("collection_url:","")
        cid = queryVal.replace("https://registry.cdlib.org/api/v1/collection/","")
        cid = cid.replace("/","")
        sQuery = 'collection_url:"{}"'.format(queryVal)
    except:
        print "Error, not valid JSON / SOLR output"
        return None

    print "Matching records in SOLR-TEST by {} for {}".format(
        matchField,
        sQuery)

    z = open('CSPHERE_IDS.txt', "a+")
    if contents["response"]["numFound"] is not 0:
        z.write("\n# {}\n# match field: {}\n\n".format(queryVal, matchField))
    for doc in contents["response"]["docs"]:
        prodID = doc["id"]
        matchVal = doc[matchField]
        if isinstance(matchVal, list):
            matchVal = matchVal[0]
        matchVal = matchVal.replace(" ","\ ")
        fullQuery = '{} AND {}:*{}*'.format(
            sQuery,
            matchField,
            matchVal)
        old_ID,new_ID = get_test_id(fullQuery,
                                    matchField,
                                    prodID,
                                    matchVal,
                                    cid,
                                    exact_match)
        if new_ID != "NOT FOUND":
            reCount += 1
            print "{} --> {}".format(old_ID, new_ID)
            z.write("{} {}\n".format(old_ID, new_ID))
        else:
            print "{} -- {}".format(old_ID, new_ID)
    print "{} matches found".format(reCount)
    z.write("\n# {} matches found {}\n\n\n".format(reCount, queryVal))
    z.close()
    f.close()


if __name__=='__main__':
    parser = argparse.ArgumentParser('This script takes as input the JSON ' \
'file generated by external-redirect-get-solr_prod-id.py and generates a ' \
'CSV pairing the old SOLR-PROD URLs with the corresponding new SOLR-TEST URLs' \
'\nUsage: external-redirect-generate-URL-redirect-map.py [JSON file]' )
    parser.add_argument('inFile')
    parser.add_argument(
        '--exact_match',
        action='store_true',
        default=False,
        help='No * wildcard matching, exact matching only. If more than'
        ' one match found in SOLR-TEST, redirect to SOLR query for'
        ' {match_field}:{match_value} (DEFAULT: false, add * wildcard'
        ' before and after {match_value}, return first SOLR query'
        ' result as match'
    )
    argv = parser.parse_args()
    kwargs = {}
    if not argv.inFile:
        raise Exception(
            "Please input valid JSON file")
    if not argv.exact_match:
        argv.exact_match = False
    main(argv.inFile, argv.exact_match)

# Copyright © 2016, Regents of the University of California
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# - Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
# - Neither the name of the University of California nor the names of its
#   contributors may be used to endorse or promote products derived from this
#   software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
