version: 2.1

jobs:
  update_openapi:
    docker:
      - image: cimg/go:1.22.5

    working_directory: ~/project

    steps:
      - checkout

      - run:
          name: Clone zklighter-perps repository
          command: |
            git clone -b << pipeline.parameters.BE_BRANCH >> --depth 1 https://${GITHUB_TOKEN}@github.com/elliottech/zklighter-perps.git

      - run:
          name: Download goctl-swagger binary
          command: |
            mv goctl-swagger-amd zklighter-perps/service/apiserver
            cd zklighter-perps/service/apiserver
            chmod +x goctl-swagger-amd

      - run:
          name: Run goctl api plugin
          command: |
            cd zklighter-perps/service/apiserver
            GO111MODULE=on go install github.com/zeromicro/go-zero/tools/goctl@v1.6.6
            sed 's/struct{}/{}/g' server.api > temp.txt && cp temp.txt server.api && rm temp.txt
            goctl api plugin --plugin ./goctl-swagger-amd="swagger -filename openapi.json -host mainnet.zklighter.elliot.ai -schemes https" --api server.api --dir .

      - run:
          name: openapi.json Post Process
          command: |
            cd zklighter-perps/service/apiserver
            jq 'del(.paths["/api/v1/feedback"], .definitions["ReqSendFeedback"], .paths["/api/v1/ws_status"], .paths["/stream"], .paths["/api/v1/permission"])' openapi.json > temp.json && mv temp.json openapi.json
            jq 'walk(if type == "object" then with_entries(select(.key != "")) else . end)'  openapi.json > temp.json && mv temp.json openapi.json
            jq 'walk(if type == "object" and has("summary") then .description = .summary else . end)' openapi.json > temp.json && mv temp.json openapi.json
            jq 'walk(if type == "object" and has("operationId") then .summary = .operationId else . end)' openapi.json > temp.json && mv temp.json openapi.json
            jq 'walk(if type == "object" and has("responses") then .responses["400"] = { "description": "Bad request", "schema": { "$ref": "#/definitions/ResultCode" } } else . end)' openapi.json > tmp.json && mv tmp.json openapi.json
            jq 'walk(if type == "object" and .name == "types" then .type="array" | .items={"type":"integer", "format":"uint8"} | del(.format)  else . end)' openapi.json > tmp.json && mv tmp.json openapi.json
            sed 's/"-",//g' openapi.json > temp.txt && mv temp.txt openapi.json

      - store_artifacts:
          path: ~/project/zklighter-perps/service/apiserver/openapi.json

      - persist_to_workspace:
          root: ~/project/zklighter-perps/service/apiserver
          paths:
            - openapi.json

  openapi_postprocess:
    docker:
      - image: cimg/python:3.10.0
    working_directory: ~/project
    steps:
      - checkout

      - attach_workspace:
          at: /tmp/workspace

      - run:
          name: Get openapi.json from workspace
          command: |
            cp /tmp/workspace/openapi.json ./.circleci

      - run:
          name: Run postprocess script
          command: |
            cd ./.circleci
            python3 openapi_postprocess.py

      - store_artifacts:
          path: ~/project/.circleci/openapi.json

      - persist_to_workspace:
          root: ~/project/.circleci
          paths:
            - openapi.json

  update_ts_sdk:
    docker:
      - image: cimg/openjdk:21.0.2
    working_directory: ~/project
    steps:
      - checkout

      - attach_workspace:
          at: /tmp/workspace

      - run:
          name: Get openapi.json from workspace
          command: |
            cp /tmp/workspace/openapi.json .

      - run:
          name: Download OpenAPI Generator JAR
          command: |
            wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.7.0/openapi-generator-cli-7.7.0.jar -O openapi-generator-cli.jar

      - run:
          name: Generate TS client using OpenAPI Generator
          command: |
            java -jar openapi-generator-cli.jar generate -i ./openapi.json -g typescript-fetch -o . -c config.yaml
      - run:
          name: git status
          command: |
            if git status | grep -q "nothing to commit"; then 
                exit 1; 
            fi
      - run:
          name: Increase package version
          command: |
            jq '.version |= (split(".") | .[2] = ((.[2] | tonumber) + 1 | tostring) | join("."))' package.json > tmp.json && mv tmp.json package.json

      - run:
          name: push to new branch
          command: |
            git remote remove origin
            git remote add origin https://${GITHUB_TOKEN}@github.com/elliottech/zklighter-perps-ts

            git config --global user.email "hasan@circleci.com"
            git config --global user.name "CircleCI Hasan"
            export BRANCH_NAME=`date +%s`
            git checkout -b $BRANCH_NAME
            git add .
            git commit -m "Update SDK"
            git push origin $BRANCH_NAME

            BE_BRANCH=<< pipeline.parameters.BE_BRANCH >>

            PR_URL=$(curl -X POST -H "Authorization: Bearer ${GITHUB_TOKEN}" -d '{"title": "'$BE_BRANCH'", "head": "'$BRANCH_NAME'", "base": "main"}' https://api.github.com/repos/elliottech/zklighter-perps-ts/pulls | jq -r '.html_url')
            curl -X POST -H 'Content-type: application/json' --data '{"text":"TypeScript SDK has been updated. Check the PR here: '$PR_URL'", "type": "mrkdwn"}' ${SLACK_URL}

  update_npm_package:
    docker:
      - image: cimg/node:22.4.1

    steps:
      - checkout
      - run:
          name: Remove binaries
          command: |
            rm -rf goctl-swagger-amd
            rm -rf openapi-generator-cli.jar
      - run:
          name: Publish npm package
          command: |
            git config --global user.email "hasan@lighter.xyz"
            git config --global user.name "CircleCI Hasan"
            npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN
            npm publish

parameters:
  update_ts_sdk:
    default: false
    type: boolean
  BE_BRANCH:
    type: string
    default: "main"

workflows:
  version: 2
  update_ts_sdk:
    when: << pipeline.parameters.update_ts_sdk >>
    jobs:
      - update_openapi:
          filters:
            branches:
              only: main
      - openapi_postprocess:
          filters:
            branches:
              only: main
          requires:
            - update_openapi
      - update_ts_sdk:
          filters:
            branches:
              only: main
          requires:
            - openapi_postprocess

  update_npm_package:
    when:
      not: << pipeline.parameters.update_ts_sdk >>
    jobs:
      - update_npm_package:
          filters:
            branches:
              only: main

