# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_CanLii.ipynb.

# %% auto 0
__all__ = ['canlii_api']

# %% ../nbs/00_CanLii.ipynb 3
import pandas as pd
import requests
import json
import sys

# %% ../nbs/00_CanLii.ipynb 4
class canlii_api:
    "Enter your secret API key and your preferred language ('en' or 'fr')"
    def __init__(self, key='', language='en'):
        self.key = key
        self.language = language
    
    def isolate_id(self, dictionary):
        #used for the list_decisions call
        #some databases return caseId as a language
        try:
            case_id = dictionary[self.language]
        except:
            if self.language == 'en':
                case_id = dictionary['fr']
            else:
                case_id = dictionary['en']
        return case_id
    
    def check_status(self, res):
        if res.status_code == 200:
            pass
        elif res.status_code == 429:
            raise TypeError("Quota exceeded.")
        elif res.status_code == 403:
            raise TypeError("Invalid API key.")
        else:
            raise TypeError(f'Error code {res.status_code}.')
    
        
    def list_tribunals(self):
        "Returns list of CanLii caselaw databases"
        res = requests.get(f'https://api.canlii.org/v1/caseBrowse/{self.language}/?api_key={self.key}')
        self.check_status(res)
        
        json_res = json.loads(res.text)
        df = pd.DataFrame.from_dict(json_res['caseDatabases'])
        return df
    
    def list_decisions(self, databaseId, descending=True, resultCount=10, decision_date_after='', decision_date_before=''):
        if descending == True: 
            offset = 0 
        else: offset = 1

        res = requests.get(f'https://api.canlii.org/v1/caseBrowse/{self.language}/{databaseId}/?offset={offset}&resultCount={resultCount}&decisionDateBefore={decision_date_before}&decisionDateAfter={decision_date_after}&api_key={self.key}')
        self.check_status(res)
            
        json_res = json.loads(res.text)
        df = pd.DataFrame.from_dict(json_res['cases'])
        df['caseId'] = df['caseId'].apply(self.isolate_id)
        df.drop(columns=['databaseId'], inplace=True)
        return df
    
    def case_metadata(self, databaseId, caseId):
        res = requests.get(f'https://api.canlii.org/v1/caseBrowse/{self.language}/{databaseId}/{caseId}/?api_key={self.key}')
        self.check_status(res)
        
        json_res = json.loads(res.text)
        df = pd.Series(json_res)
        return df
    
    def internal_cites(self, databaseId, caseId):
        "Get a list of all the cases your target case cites."
        res = requests.get(f'https://api.canlii.org/v1/caseCitator/en/{databaseId}/{caseId}/citedCases?api_key={self.key}')
        self.check_status(res)

        json_res = json.loads(res.text)
        try:
            df = pd.DataFrame.from_dict(json_res['citedCases'])
            df['caseId'] = df['caseId'].apply(self.isolate_id)
            df.drop(columns=['databaseId'], inplace=True)
        except:
            df = pd.DataFrame()
        return df
    
    def legislation_cites(self, databaseId, caseId):
        "Get a list of all the legislation your target case cites."
        res = requests.get(f'https://api.canlii.org/v1/caseCitator/en/{databaseId}/{caseId}/citedLegislations?api_key={self.key}')
        self.check_status(res)
        
        json_res = json.loads(res.text)
        try:
            df = pd.DataFrame.from_dict(json_res['citedLegislations'])
        except:
            df = pd.DataFrame()
        return df
    
    def external_cites(self, databaseId, caseId):
        "Get a list of all the cases that cite your target case."
        res = requests.get(f'https://api.canlii.org/v1/caseCitator/en/{databaseId}/{caseId}/citingCases?api_key={self.key}')
        self.check_status(res)
        
        json_res = json.loads(res.text)
        try:
            df = pd.DataFrame.from_dict(json_res['citingCases'])
            df['caseId'] = df['caseId'].apply(self.isolate_id)
            df.drop(columns=['databaseId'], inplace=True)
        except:
            df = pd.DataFrame()
        return df
    
    def citations_edge_list(self, df, databaseId):
    
        citations_edge_list = pd.DataFrame()
        count = 0
        total_number_pulls = df.shape[0]

        for index,row in df.iterrows():
            title = df.loc[index,'title']
            caseId = df.loc[index,'caseId']
            case_citation = df.loc[index,'citation']
            
            cited_df = pd.DataFrame()
            cited_df = self.internal_cites(databaseId=databaseId, caseId=caseId)
            
            try:
                cited_df['original_caseID'] = caseId
                cited_df['original_case_citation'] = case_citation
                cited_df['original_case_title'] = title

                cited_df.rename(columns={'caseId':'cited_case_caseId', 'citation':'cited_case_citation', 'title':'cited_case_title'}, inplace=True)
                cited_df = cited_df[['original_caseID', 'original_case_citation', 'original_case_title','cited_case_caseId', 'cited_case_title','cited_case_citation']]
            except:
                cited_df['original_caseID'] = caseId
                cited_df['error'] = 'y'
                

            citations_edge_list = pd.concat([citations_edge_list,cited_df], axis=0)

            count = count+1
            r = count % 100
            if r == 0:
                print(f'Completed {count} API calls out of {total_number_pulls} requested.')
        
        citations_edge_list.reset_index(drop=True, inplace=True)
        
        return citations_edge_list
    
    def keywords_edge_list(self, df, databaseId):
        keywords_edge_list = pd.DataFrame()
        total_number_pulls = df.shape[0]

        for index,row in df.iterrows():
            databaseId = databaseId
            caseId = df.loc[index,'caseId']
            res = self.case_metadata(databaseId=databaseId, caseId=caseId)

            keywords = res['keywords'].split(' — ')

            case_keywords_df = pd.DataFrame()
            count = 0

            for keyword in keywords:
                case_keywords_df.loc[count,'keyword'] = keyword
                count += 1

            case_keywords_df['databaseId'] = res['databaseId']
            case_keywords_df['caseId'] = res['caseId']
            case_keywords_df['title'] = res['title']
            case_keywords_df['citation'] = res['citation']
            case_keywords_df['decisionDate'] = res['decisionDate']

            case_keywords_df = case_keywords_df[['databaseId', 'caseId', 'title', 'citation', 'decisionDate', 'keyword']]

            keywords_edge_list = pd.concat([keywords_edge_list, case_keywords_df], axis=0)
            
            count = count+1
            r = count % 100
            if r == 0:
                print(f'Completed {count} API calls out of {total_number_pulls} requested.')

        keywords_edge_list.reset_index(drop=True, inplace=True)
        
        return keywords_edge_list
    
    def keywords_edge_list_topic2topic(self, df, databaseId):
        keywords_edge_list = pd.DataFrame()

        for index,row in df.iterrows():
            databaseId = databaseId
            caseId = df.loc[index,'caseId']
            res = self.case_metadata(databaseId=databaseId, caseId=caseId)

            keywords = res['keywords'].split(' — ')

            edges = []

            for keyword in keywords:
                for keyword2 in keywords:
                    if keyword == keyword2:
                        pass
                    else:
                        item = (keyword, keyword2)
                        edges.append(item)
                keywords.remove(keyword)

            case_keywords_df = pd.DataFrame()
            count = 0

            for item in edges:
                case_keywords_df.loc[count,'keyword_1'] = item[0]
                case_keywords_df.loc[count,'keyword_2'] = item[1]
                count += 1

            case_keywords_df['databaseId'] = res['databaseId']
            case_keywords_df['caseId'] = res['caseId']
            case_keywords_df['title'] = res['title']
            case_keywords_df['citation'] = res['citation']
            case_keywords_df['decisionDate'] = res['decisionDate']

            case_keywords_df = case_keywords_df[['databaseId', 'caseId', 'title', 'citation', 'decisionDate', 'keyword_1', 'keyword_2']]

            keywords_edge_list = pd.concat([keywords_edge_list, case_keywords_df], axis=0)
        
        keywords_edge_list.reset_index(drop=True, inplace=True)
        
        return keywords_edge_list
