import requests
import json
import pandas as pd
import io
from IPython.display import Image

# Basic Setup
PORT_NUMBER = 1234
BASE = 'http://localhost:' + str(PORT_NUMBER) + '/v1/'

# KEGG API
KEGG_API_URL = 'http://rest.kegg.jp/'

# Header for posting data to the server as JSON
HEADERS = {'Content-Type': 'application/json'}

requests.get(BASE)

"""
Explanation: Under Construction!
Working with External Web Services
This example shows how to use external services to set up Cytoscape session with pathways

Cytoscape 3.2.0 beta
KEGGScape 0.7.x
cy-rest 0.9.x or later

Input and Output

Input - Disease name
Output - Cytoscape session file containing all KEGG pathways known to be related to the disease.

External Services
KEGG API
TogoWS
End of explanation
"""


# Find information about cancer from KEGG disease database.
query = 'cancer'

res = requests.get(KEGG_API_URL + '/find/disease/' + query)
pathway_list = res.content.decode('utf8')

disease_df = pd.read_csv(io.StringIO(pathway_list), delimiter='\t',  header=None, names=['id', 'name'])
disease_df

"""
Explanation: Get list of entries about cancer
End of explanation
"""


disease_ids = disease_df['id']
disease_urls = disease_ids.apply(lambda x: KEGG_API_URL + 'get/' + x)

def disease_parser(entry):
    lines = entry.split('\n')
    data = {}
    
    last_key = None
    for line in lines:
        if '///' in line:
            return data
        
        parts = line.split(' ')
        if parts[0] is not None and len(parts[0]) != 0:
            last_key = parts[0]
            data[parts[0]] = line.replace(parts[0], '').strip()
        else:
            last_val = data[last_key]
            data[last_key] = last_val + '|' + line.strip()
    return data   

result = []
for url in disease_urls:
        res = requests.get(url)
        rows = disease_parser(res.content)
        result.append(rows)

disease_df = pd.DataFrame(result)
pathways = disease_df['PATHWAY'].dropna().unique()

p_urls = []
for pathway in pathways:
    entries = pathway.split('|')
    for en in entries:
        url = KEGG_API_URL + 'get/' + en.split(' ')[0].split('(')[0] + '/kgml'
        p_urls.append(url)

"""
Explanation: Get pathway list
End of explanation
"""


def create_from_list(network_list):
    server_res = requests.post(BASE + 'networks?source=url&collection=' + query, data=json.dumps(network_list), headers=HEADERS)
    return json.loads(server_res.content)

requests.delete(BASE + 'networks')

url_list = list(set(p_urls))
pathway_suids = create_from_list(url_list)

# Check the result.
print(json.dumps(pathway_suids[0], indent=4))

Image(url=BASE+'networks/' + str(pathway_suids[0]['networkSUID'][0]) + '/views/first.png', embed=True)

"""
Explanation: Import all cancer related pathways
End of explanation
"""


# Find SUID for Cancer Overview Pathway
cancer_overview_pathway_suid = None

for result in pathway_suids:
    if 'hsa05200' in result['source']:
        cancer_overview_pathway_suid = result['networkSUID'][0]
        break
        

rows_res = requests.get(BASE + 'networks/' + str(cancer_overview_pathway_suid) + '/tables/defaultnode/rows')

# Convert it to DataFrame
cancer_df = pd.read_json(rows_res.content)

genes = cancer_df[cancer_df['KEGG_NODE_TYPE'] == 'gene']

gene_set = set([])

count = 0
converted = ''
query_str = ''
for gene_list in genes['KEGG_ID']:
    for gene in gene_list:
        gene_set.add(gene)
        query_str = query_str + gene + '+'
        count  = count + 1
        if count == 99:
            conversion = requests.get('http://rest.kegg.jp/conv/uniprot/' + query_str)
            converted = converted + conversion.content
            count = 0
            query_str = ''
            
conversion = requests.get('http://rest.kegg.jp/conv/uniprot /' + query_str)
converted = converted + conversion.content    

print(len(gene_set))

conversion_map = pd.read_csv(io.StringIO(converted.decode('utf8')), delimiter='\t',  header=None, names=['KEGG_ID', 'uniprot_id'])
id_list = conversion_map.drop_duplicates()
type(id_list)

id_list['uniprot_id'] = id_list['uniprot_id'].apply(lambda x: x.split(':')[1])

print(json.dumps(json.loads(id_list.to_json(orient='records')), indent=4))

new_column = {
    'name': 'KEGG_ID_TOP',
    'type': 'String'
}

first_key_res = requests.post(BASE + 'networks/' + str(cancer_overview_pathway_suid) + '/tables/defaultnode/columns', data=json.dumps(new_column), headers=HEADERS)


genes['KEGG_ID_TOP'] = genes.apply(lambda row:  row['KEGG_ID'][0], axis=1)

sub_table= genes[['SUID', 'KEGG_ID_TOP']]
sub_table.columns = ['SUID', 'KEGG_ID']

merged = pd.merge(sub_table, id_list, on='KEGG_ID')
merged.columns = ['SUID', 'KEGG_ID_TOP', 'UNIPROT_ID']
table_data = json.loads(merged.to_json(orient='records'))

new_table_data = {
    'data': table_data
}

# print(json.dumps(new_table_data, indent=4))

res = requests.put(BASE + 'networks/' + str(cancer_overview_pathway_suid) + '/tables/defaultnode', data=json.dumps(new_table_data), headers=HEADERS)

merged[['UNIPROT_ID']].to_clipboard(index=False, header=False)

"""
Explanation: Result

Annotate Pathways by External Services

Get list of genes in the pathway
ID Conversion
Interactions
End of explanation
"""


