#!/usr/bin/env python3
"""
Script pour recréer toutes les relations Hasura avec les noms camelCase.
Utilise l'API metadata Hasura pour créer les relations manquantes.
"""
import json
import subprocess
import sys

ADMIN_SECRET = 'Digitribe972'
METADATA_URL = 'http://localhost:8082/v1/metadata'
GRAPHQL_URL = 'http://localhost:8082/v1/graphql'

def graphql_query(query):
    """Execute a GraphQL query and return the result."""
    r = subprocess.run(
        ['curl', '-s', '-X', 'POST', GRAPHQL_URL,
         '-H', f'x-hasura-admin-secret: {ADMIN_SECRET}',
         '-H', 'Content-Type: application/json',
         '-d', json.dumps({"query": query})],
        capture_output=True, text=True, timeout=15
    )
    return json.loads(r.stdout)

def metadata_command(payload):
    """Execute a metadata command and return the result."""
    r = subprocess.run(
        ['curl', '-s', '-X', 'POST', METADATA_URL,
         '-H', f'x-hasura-admin-secret: {ADMIN_SECRET}',
         '-H', 'Content-Type: application/json',
         '-d', json.dumps(payload)],
        capture_output=True, text=True, timeout=15
    )
    return json.loads(r.stdout)

def test_relation(table, relation, fields='{ id }'):
    """Test if a relation works by querying it."""
    query = f'{{ {table}(where: {{id: {{_eq: "CP001"}}}}) {{ id {relation} {fields} }} }}'
    result = graphql_query(query)
    if 'errors' in result:
        return False, result['errors'][0]['message'][:100]
    return True, "OK"

def create_relation(table, name, rel_type, remote_table, col_map):
    """Create a relationship in Hasura."""
    if rel_type == 'object':
        payload = {
            "type": "pg_create_object_relationship",
            "args": {
                "source": "default",
                "table": {"schema": "public", "name": table},
                "name": name,
                "using": {
                    "manual_configuration": {
                        "remote_table": {"schema": "public", "name": remote_table},
                        "column_mapping": col_map
                    }
                }
            }
        }
    else:
        payload = {
            "type": "pg_create_array_relationship",
            "args": {
                "source": "default",
                "table": {"schema": "public", "name": table},
                "name": name,
                "using": {
                    "manual_configuration": {
                        "remote_table": {"schema": "public", "name": remote_table},
                        "column_mapping": col_map
                    }
                }
            }
        }
    
    result = metadata_command(payload)
    if 'message' in result and result['message'] == 'success':
        return True
    elif 'error' in result:
        if 'already exists' in result['error']:
            return True  # Already exists, that's OK
        print(f"  ERROR: {result['error'][:200]}")
        return False
    return False

def main():
    print("=== Diagnostic des relations Hasura ===\n")
    
    # Test critical relations
    critical_relations = [
        ("ChargingStations", "location", "{ id name }"),
        ("ChargingStations", "evses", "{ id evseId }"),
        ("ChargingStations", "connectors", "{ id status }"),
        ("ChargingStations", "transactions", "{ id }"),
        ("ChargingStations", "latestStatusNotifications", "{ statusNotification { connectorStatus } }"),
        ("ChargingStations", "tenant", "{ id name }"),
        ("Evses", "connectors", "{ id status }"),
        ("Transactions", "chargingStation", "{ id }"),
        ("Transactions", "evse", "{ id }"),
        ("Transactions", "connector", "{ id }"),
        ("Transactions", "location", "{ id name }"),
        ("LatestStatusNotifications", "statusNotification", "{ connectorStatus }"),
    ]
    
    print("Test des relations critiques:")
    all_ok = True
    for table, relation, fields in critical_relations:
        ok, msg = test_relation(table, relation, fields)
        status = "OK" if ok else "FAIL"
        print(f"  {status}: {table}.{relation}")
        if not ok:
            all_ok = False
            print(f"    -> {msg}")
    
    if all_ok:
        print("\n=== Toutes les relations fonctionnent ! ===")
        return
    
    print("\n=== Recréation des relations manquantes ===\n")
    
    # Define all relations to create
    relations = [
        # ChargingStations
        ("ChargingStations", "location", "object", "Locations", {"locationId": "id"}),
        ("ChargingStations", "tenant", "object", "Tenants", {"tenantId": "id"}),
        ("ChargingStations", "evses", "array", "Evses", {"id": "stationId"}),
        ("ChargingStations", "connectors", "array", "Connectors", {"id": "stationId"}),
        ("ChargingStations", "transactions", "array", "Transactions", {"id": "stationId"}),
        ("ChargingStations", "latestStatusNotifications", "array", "LatestStatusNotifications", {"id": "stationId"}),
        ("ChargingStations", "variableAttributes", "array", "VariableAttributes", {"id": "stationPkId"}),
        
        # Evses
        ("Evses", "connectors", "array", "Connectors", {"evseId": "evseId"}),
        ("Evses", "transactions", "array", "Transactions", {"evseId": "evseId"}),
        ("Evses", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        
        # Connectors
        ("Connectors", "evse", "object", "Evses", {"evseId": "id"}),
        ("Connectors", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        
        # Transactions
        ("Transactions", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        ("Transactions", "evse", "object", "Evses", {"evseId": "id"}),
        ("Transactions", "connector", "object", "Connectors", {"connectorId": "id"}),
        ("Transactions", "authorization", "object", "Authorizations", {"authorizationId": "id"}),
        ("Transactions", "location", "object", "Locations", {"locationId": "id"}),
        
        # LatestStatusNotifications
        ("LatestStatusNotifications", "statusNotification", "object", "StatusNotifications", {"statusNotificationId": "id"}),
        ("LatestStatusNotifications", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        
        # Locations
        ("Locations", "chargingStations", "array", "ChargingStations", {"locationId": "id"}),
        
        # StatusNotifications
        ("StatusNotifications", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        ("StatusNotifications", "evse", "object", "Evses", {"evseId": "id"}),
        ("StatusNotifications", "connector", "object", "Connectors", {"connectorId": "id"}),
        
        # Authorizations
        ("Authorizations", "transactions", "array", "Transactions", {"authorizationId": "id"}),
        ("Authorizations", "chargingStation", "object", "ChargingStations", {"stationId": "id"}),
        
        # Tenants
        ("Tenants", "chargingStations", "array", "ChargingStations", {"tenantId": "id"}),
        ("Tenants", "evses", "array", "Evses", {"tenantId": "id"}),
        ("Tenants", "connectors", "array", "Connectors", {"tenantId": "id"}),
        ("Tenants", "transactions", "array", "Transactions", {"tenantId": "id"}),
        ("Tenants", "locations", "array", "Locations", {"tenantId": "id"}),
        ("Tenants", "authorizations", "array", "Authorizations", {"tenantId": "id"}),
        ("Tenants", "tenantPartners", "array", "TenantPartners", {"tenantId": "id"}),
        ("Tenants", "statusNotifications", "array", "StatusNotifications", {"tenantId": "id"}),
        ("Tenants", "latestStatusNotifications", "array", "LatestStatusNotifications", {"tenantId": "id"}),
        ("Tenants", "variableAttributes", "array", "VariableAttributes", {"tenantId": "id"}),
        ("Tenants", "chargingProfiles", "array", "ChargingProfiles", {"tenantId": "id"}),
        ("Tenants", "chargingSchedules", "array", "ChargingSchedules", {"tenantId": "id"}),
        ("Tenants", "salesTariffs", "array", "SalesTariffs", {"tenantId": "id"}),
        ("Tenants", "messageInfos", "array", "MessageInfos", {"tenantId": "id"}),
        ("Tenants", "securityEvents", "array", "SecurityEvents", {"tenantId": "id"}),
        ("Tenants", "certificates", "array", "Certificates", {"tenantId": "id"}),
        ("Tenants", "boots", "array", "Boots", {"tenantId": "id"}),
        ("Tenants", "asyncJobStatuses", "array", "AsyncJobStatuses", {"tenantId": "id"}),
        ("Tenants", "eventData", "array", "EventData", {"tenantId": "id"}),
        ("Tenants", "subscriptions", "array", "Subscriptions", {"tenantId": "id"}),
        ("Tenants", "reservations", "array", "Reservations", {"tenantId": "id"}),
        ("Tenants", "transactionEvents", "array", "TransactionEvents", {"tenantId": "id"}),
        ("Tenants", "startTransactions", "array", "StartTransactions", {"tenantId": "id"}),
        ("Tenants", "stopTransactions", "array", "StopTransactions", {"tenantId": "id"}),
        ("Tenants", "meterValues", "array", "MeterValues", {"tenantId": "id"}),
        ("Tenants", "chargingStationNetworkProfiles", "array", "ChargingStationNetworkProfiles", {"tenantId": "id"}),
        ("Tenants", "serverNetworkProfiles", "array", "ServerNetworkProfiles", {"tenantId": "id"}),
        ("Tenants", "componentVariables", "array", "ComponentVariables", {"tenantId": "id"}),
        ("Tenants", "components", "array", "Components", {"tenantId": "id"}),
        ("Tenants", "variables", "array", "Variables", {"tenantId": "id"}),
        ("Tenants", "evseTypes", "array", "EvseTypes", {"tenantId": "id"}),
        ("Tenants", "compositeSchedules", "array", "CompositeSchedules", {"tenantId": "id"}),
        ("Tenants", "changeConfigurations", "array", "ChangeConfigurations", {"tenantId": "id"}),
        ("Tenants", "chargingStationSequences", "array", "ChargingStationSequences", {"tenantId": "id"}),
        ("Tenants", "chargingStationSecurityInfos", "array", "ChargingStationSecurityInfos", {"tenantId": "id"}),
        ("Tenants", "localListAuthorizations", "array", "LocalListAuthorizations", {"tenantId": "id"}),
        ("Tenants", "localListVersionAuthorizations", "array", "LocalListVersionAuthorizations", {"tenantId": "id"}),
        ("Tenants", "localListVersions", "array", "LocalListVersions", {"tenantId": "id"}),
        ("Tenants", "sendLocalListAuthorizations", "array", "SendLocalListAuthorizations", {"tenantId": "id"}),
        ("Tenants", "sendLocalLists", "array", "SendLocalLists", {"tenantId": "id"}),
        ("Tenants", "deleteCertificateAttempts", "array", "DeleteCertificateAttempts", {"tenantId": "id"}),
        ("Tenants", "installCertificateAttempts", "array", "InstallCertificateAttempts", {"tenantId": "id"}),
        ("Tenants", "installedCertificates", "array", "InstalledCertificates", {"tenantId": "id"}),
    ]
    
    created = 0
    failed = 0
    
    for table, name, rel_type, remote_table, col_map in relations:
        print(f"Creating {table}.{name}...", end=" ")
        if create_relation(table, name, rel_type, remote_table, col_map):
            print("OK")
            created += 1
        else:
            print("FAIL")
            failed += 1
    
    print(f"\n=== Résultat: {created} créées, {failed} échouées ===")
    
    # Retest critical relations
    print("\n=== Vérification finale ===\n")
    all_ok = True
    for table, relation, fields in critical_relations:
        ok, msg = test_relation(table, relation, fields)
        status = "OK" if ok else "FAIL"
        print(f"  {status}: {table}.{relation}")
        if not ok:
            all_ok = False
    
    if all_ok:
        print("\n🎉 Toutes les relations fonctionnent !")
    else:
        print("\n❌ Certaines relations ne fonctionnent pas encore.")

if __name__ == '__main__':
    main()
