#!/bin/bash

version=$1 # e.g. 2024-07

# modules
db_control_module="db_control"
db_data_module="db_data"
inference_module="inference"
admin_module="admin"

# generated grpc output destination paths
# db_data_destination must align with the option go_package in the proto file: 
# https://github.com/pinecone-io/apis/blob/d1d005e75cc9fe9a5c486ef9218fe87b57765961/src/release/db/data/data.proto#L3
db_data_destination="internal/gen/${db_data_module}"
db_control_destination="internal/gen/${db_control_module}"
inference_destination="internal/gen/${inference_module}"
admin_destination="internal/gen/${admin_module}"

# version file
version_file="internal/gen/api_version.go"

# generated oas file destination paths
db_data_rest_destination="${db_data_destination}/rest"
db_data_oas_file="${db_data_rest_destination}/${db_data_module}_${version}.oas.go"
db_control_oas_file="${db_control_destination}/${db_control_module}_${version}.oas.go"
inference_oas_file="${inference_destination}/${inference_module}_${version}.oas.go"
admin_oas_file="${admin_destination}/${admin_module}_${version}.oas.go"

set -eux -o pipefail

update_apis_repo() {
    echo "Updating apis repo"
    pushd codegen/apis
            git fetch
            git checkout main
            git pull
            just clean
            just build
    popd
}

verify_spec_version() {
    local version=$1
    echo "Verifying spec version has been provided: $version"
    if [ -z "$version" ]; then
        echo "Version is required"
        exit 1
    fi 

    verify_directory_exists "codegen/apis/_build/${version}"
}

verify_directory_exists() {
	local directory=$1
	if [ ! -d "$directory" ]; then
		echo "Directory does not exist at $directory"
		exit 1
	fi
}

generate_oas_client() {
    local module=$1
    local destination=$2

    # source oas file for module and version
    oas_file="codegen/apis/_build/${version}/${module}_${version}.oas.yaml"

    oapi-codegen --package=${module} \
    --generate types,client \
    "${oas_file}" > "${destination}"
}

generate_proto_client() {
    local module=$1

    # source proto file for module and version
    proto_file="codegen/apis/_build/${version}/${module}_${version}.proto"

    protoc --experimental_allow_proto3_optional \
    --proto_path=codegen/apis/vendor/protos \
    --proto_path=codegen/apis/_build/${version} \
    --go_opt=module="github.com/pinecone-io/go-pinecone" \
    --go-grpc_opt=module="github.com/pinecone-io/go-pinecone" \
    --go_out=. \
    --go-grpc_out=. \
    "${proto_file}" 
}

generate_version_file() {
    echo "Generating version file"
    cat > "${version_file}" <<EOL
// Code generated by build-clients.sh - DO NOT EDIT.
package gen

const PineconeApiVersion = "${version}"
EOL
}

update_apis_repo
verify_spec_version $version

# Clear internal/gen/* contents
rm -rf internal/gen/*

# Generate db_control oas client
rm -rf "${db_control_destination}"
mkdir -p "${db_control_destination}"
generate_oas_client $db_control_module $db_control_oas_file

# Generate inference oas client
rm -rf "${inference_destination}"
mkdir -p "${inference_destination}"
generate_oas_client $inference_module $inference_oas_file

# Generate admin oas client
rm -rf "${admin_destination}"
mkdir -p "${admin_destination}"
generate_oas_client $admin_module $admin_oas_file

# Generate db_data oas and proto clients
rm -rf "${db_data_destination}"
mkdir -p "${db_data_destination}"
mkdir -p "${db_data_rest_destination}"

generate_oas_client $db_data_module $db_data_oas_file
generate_proto_client $db_data_module

# Generate version file
rm -rf "${version_file}"
generate_version_file