#!/usr/bin/env python
###############################################################################
# $Id$
#
#  Project:  PROJ
#  Purpose:  Populate data/sql/wgs84_realizations_concatenated_operations.sql
#  Author:   Even Rouault <even.rouault at spatialys.com>
#
###############################################################################
#  Copyright (c) 2025, Even Rouault <even.rouault at spatialys.com>
#
# SPDX-License-Identifier: MIT
###############################################################################

import os

script_dir_name = os.path.dirname(os.path.realpath(__file__))
sql_dir_name = os.path.join(os.path.dirname(script_dir_name), 'data', 'sql')

out_filename = os.path.join(sql_dir_name, 'wgs84_realizations_concatenated_operations') + '.sql'
#print(out_filename)

def sanitize_crs_name_for_code(name):
    return name.replace('(', '_').replace(')', '').replace(' ','_').replace('__','_').upper()

def gen_transformations(sql, transformations, crs_dict):
    for i in range(len(transformations)):
        if transformations[i][0] == "WGS 84 (G1150)" and transformations[i][1] == "WGS 84 (G1762)":
            continue
        for j in range(i+1,len(transformations)):
            if transformations[j][0] == "WGS 84 (G1150)" and transformations[j][1] == "WGS 84 (G1762)":
                continue
            source_crs = transformations[i][0]
            target_crs = transformations[j][1]

            source_crs_week = 0 if source_crs == "WGS 84 (Transit)" else int(source_crs[len("WGS 84 (G"):-1])
            target_crs_week = int(target_crs[len("WGS 84 (G"):-1])

            transfm_code = sanitize_crs_name_for_code(source_crs) + "_TO_" + sanitize_crs_name_for_code(target_crs)
            transfm_name = f"{source_crs} to {target_crs}"

            source_crs_code = crs_dict[source_crs]
            target_crs_code = crs_dict[target_crs]

            step = 0
            steps_sql = []
            total_acc = 0
            for k in range(i,j+1):
                source_crs_name = transformations[k][0]
                target_crs_name = transformations[k][1]
                if source_crs_week <= 1150 and target_crs_week >= 1762 and \
                   ((source_crs_name == "WGS 84 (G1150)" and target_crs_name == "WGS 84 (G1674)") or \
                    (source_crs_name == "WGS 84 (G1674)" and target_crs_name == "WGS 84 (G1762)")):
                    continue
                step += 1
                step_code = transformations[k][2]
                acc = transformations[k][3]
                total_acc += acc
                steps_sql.append(f"INSERT INTO concatenated_operation_step VALUES('PROJ','{transfm_code}',{step},'EPSG','{step_code}','forward'); -- {source_crs_name} to {target_crs_name} (EPSG:{step_code}), {acc} m\n")

            if len(steps_sql) <= 1:
                continue

            total_acc = round(total_acc * 100) / 100.0

            sql += f"INSERT INTO concatenated_operation VALUES('PROJ','{transfm_code}','{transfm_name}','Transformation based on concatenation of transformations between WGS 84 realizations','EPSG','{source_crs_code}','EPSG','{target_crs_code}',{total_acc},NULL,0);\n"

            for step_sql in steps_sql:
                sql += step_sql

            sql += f"INSERT INTO usage VALUES('PROJ','{transfm_code}_USAGE','concatenated_operation','PROJ','{transfm_code}',\n"
            sql += "    'EPSG','1262', -- extent: World\n"
            sql += "    'EPSG','1027' -- scope: Geodesy\n"
            sql += ");\n"

            sql += "\n"

    return sql

crs_dict = {
    "WGS 84 (Transit)": 7815,
    "WGS 84 (G730)": 7656,
    "WGS 84 (G873)": 7658,
    "WGS 84 (G1150)": 7660,
    "WGS 84 (G1674)": 7662,
    "WGS 84 (G1762)": 7664,
    "WGS 84 (G2139)": 9753,
    "WGS 84 (G2296)": 10604,
}

f = open(out_filename, 'wb')
f.write("--- This file has been generated by scripts/build_wgs84_realizations_concatenated_operations.py. DO NOT EDIT !\n\n".encode('UTF-8'))

f.write("-- Concatenated accuracy is sum of accuracies\n\n".encode('UTF-8'))

sql = ""

transformations = [
    ("WGS 84 (Transit)", "WGS 84 (G730)", 9960, 0.7),  # regular Helmert
    ("WGS 84 (G730)", "WGS 84 (G873)", 9961, 0.04),    # regular Helmert
    ("WGS 84 (G873)", "WGS 84 (G1150)", 9962, 0.03),   # time-dependent Helmert
    ("WGS 84 (G1150)", "WGS 84 (G1674)", 9963, 0.02),  # time-dependent Helmert
    ("WGS 84 (G1150)", "WGS 84 (G1762)", 7668, 0.02),  # regular Helmert. Note that it doesn't go through G1674
    ("WGS 84 (G1674)", "WGS 84 (G1762)", 7667, 0.01),  # regular Helmert
    ("WGS 84 (G1762)", "WGS 84 (G2139)", 9756, 0.01),  # regular Helmert
    ("WGS 84 (G2139)", "WGS 84 (G2296)", 10607, 0.01), # regular Helmert
]

sql = gen_transformations(sql, transformations, crs_dict)

f.write(sql.encode('UTF-8'))

f.close()
