#!/bin/bash

GITDIR=${GITDIR:-`git rev-parse --show-toplevel`}
source "${GITDIR}/src/scripts/common.sh"

set -eu

do_exec cd "$(dirname "$0")"

# This script generates Go and JSON schemas from TS type definitions.
# It will also copy the TS files into the relevant frontend folder.

# NOTE: There is now a direct TS -> Go converted but for openapi we still need
# the json schema files. So we may keep using TS -> json schema -> Go.
# See https://github.com/quicktype/quicktype#generating-code-from-typescript-experimental

do_echo "Generating Go types and importing TS from schemas/v2/*.ts..."

# Create a directory to hold the generated JSON schemas
# We'll keep a single copy in the goapi API folder
SCHEMAS_DIR=${GITDIR}/src/services/goapi/api/schemas/json-v2
GO_TYPES_DIR=${GITDIR}/src/services/goapi/pkg/schemas/v2
FRONTEND_DIR=${GITDIR}/src/services/frontend/src/app/third_party_types

export GOBIN="${GOBIN:-$HOME/go/bin}"
if ! gofumpt --version ; then
  do_echo "Installing gofumpt..."
  do_exec go install mvdan.cc/gofumpt@latest
fi

# This folder should only contain the files generated by this script.
do_exec rm -f ${SCHEMAS_DIR}/*.schema.json
do_exec mkdir -p "${SCHEMAS_DIR}"
do_exec rm -f ${GO_TYPES_DIR}/*.go
do_exec mkdir -p "${GO_TYPES_DIR}"

for f in `find . -name '*.ts'` ; do
  # Skip if file content starts with '// SKIP'
  if head -n1 "$f" | grep -q '^// SKIP' ; then
    echo "Skipping $f"
    continue
  fi

  # If the file starts with `// TYPE: `, then we should generate only the
  # top-level specified type. This works around quirks with oapi-codegen.
  # Other types will get generated as dependencies.
  TYPENAME="*"  # default: generate all types
  SPECIFIC_TYPE=0
  if head -n1 "$f" | grep -q '^// TYPE:' ; then
    TYPENAME=`head -n1 "$f" | sed -e 's/^\/\/ TYPE: //'`
    SPECIFIC_TYPE=1
  fi

  # Generate JSON schemas from the TypeScript models
  SCHEMA_FILENAME="`basename $f .ts`.schema.json"
  do_exec npx --yes typescript-json-schema@0.55.0 --yes --aliasRefs --required "$f" "${TYPENAME}" -o "${SCHEMAS_DIR}/${SCHEMA_FILENAME}"
  do_exec ${GITDIR}/src/scripts/fix_eof.sh "${SCHEMAS_DIR}/${SCHEMA_FILENAME}"
  do_exec chmod -w "${SCHEMAS_DIR}/${SCHEMA_FILENAME}"

  # Generate Go types from the JSON schemas
  QUICKTYPE=quicktype@v23.0.32
  GO_PACKAGE=schemas_v2
  GO_FILENAME="`basename $f .ts`.go"
  if [ $SPECIFIC_TYPE -eq 1 ] ; then
    do_exec npx --yes ${QUICKTYPE} -s schema -l go --no-maps --no-combine-classes --package ${GO_PACKAGE} -o "${GO_TYPES_DIR}/${GO_FILENAME}" "${SCHEMAS_DIR}/${SCHEMA_FILENAME}"
  else
    do_exec npx --yes ${QUICKTYPE} -s schema -l go --no-maps --no-combine-classes --package ${GO_PACKAGE} -o "${GO_TYPES_DIR}/${GO_FILENAME}" "${SCHEMAS_DIR}/${SCHEMA_FILENAME}#/definitions/"
  fi
  do_exec gofumpt -l -w ${GO_TYPES_DIR}
  do_exec chmod -w "${GO_TYPES_DIR}/${GO_FILENAME}"
done

# Copy TypeScript files to the frontend
function sync_ts_files {
  # source and destination directories
  local src_dir="$1"
  local dest_dir="$2"

  # create a temporary directory
  local temp_dir=$(mktemp -d)

  do_exec rsync -avm --include='*.ts' --include='*/' --exclude='*' "$src_dir" "$temp_dir"

  # find all .ts files in the temporary directory, append the comment
  do_exec find "$temp_dir" -type f -name "*.ts" -exec sh -c 'echo "// DO NOT EDIT THIS FILE HERE, SEE src/lib/model-schemas/schemas/v2" >> "$1"' _ {} \;

  # use rsync to copy files from the temporary directory to the final directory
  do_exec pushd $temp_dir
  do_exec rsync -avm --include='*.ts' --include='*/' --exclude='*' . "$dest_dir"
  do_exec popd

  do_exec rm -rf "$temp_dir"
}

do_exec sync_ts_files . ${FRONTEND_DIR}
