#!/bin/bash
set -e

########################################
# Parse parameters
########################################
while [[ "$#" -gt 0 ]]; do
  case $1 in
    --hostUrl) HOST_URL="$2"; shift ;;
    --userToken) USER_TOKEN="$2"; shift ;;
    --userName) USER_NAME="$2"; shift ;;
    --sonarToken) SONAR_TOKEN="$2"; shift ;;
    --token) cavissonToken="$2"; shift ;;
    --projectKey) PROJECT_KEY="$2"; shift ;;
    --organization) ORG="$2"; shift ;;
    --solution) SOLUTION_DIR="$2"; shift ;;
    --isSonarCloud) IS_SONARCLOUD="$2"; shift ;;
    *) echo "Unknown parameter: $1"; exit 1 ;;
  esac
  shift
done

########################################
# Validate parameters
########################################
if [[ -z "$HOST_URL" || -z "$SONAR_TOKEN" || -z "$PROJECT_KEY" || -z "$USER_TOKEN" || -z "$USER_NAME" ]]; then
  echo "Required parameters: --hostUrl --sonarToken --projectKey --userToken -- userName"
  exit 1
fi

#########################################
#Finding base directory for solution
#########################################
if [[ -n "$SOLUTION_DIR" ]]; then
  echo "Scanning specific solution: $SOLUTION_DIR"

  if [[ ! -d "$SOLUTION_DIR" ]]; then
    echo "ERROR: Provided solution directory does not exist"
    exit 1
  fi

  BASE_DIR="$SOLUTION_DIR"
else
  echo "No solution provided. Scanning full repository"
  BASE_DIR="."
fi

echo "Base directory for scanning: $BASE_DIR"

########################################
# Get login
########################################

# first check the response of api, if it fails then we can assume that the token is invalid and exit with error message
#RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" -u "$SONAR_TOKEN:" "$HOST_URL/api/users/current")
#if [[ "$RESPONSE" -ne 200 ]]; then
#  echo "ERROR: Authentication failed with provided token. HTTP status code: $RESPONSE"
#  exit 1
#fi
# if the response is successful then we can proceed to get the login from the api response
#Login

#LOGIN=$(curl -s -u "$SONAR_TOKEN:" "$HOST_URL/api/users/current" | jq -r '.login')
#echo "Authenticated as: $LOGIN"


########################################
# Create project if missing
########################################
create_project_if_missing() {

  if [[ "$IS_SONARCLOUD" == true ]]; then
    PROJECT_EXISTS=$(curl -s -u "$SONAR_TOKEN:" \
      "$HOST_URL/api/projects/search?projects=$PROJECT_KEY&organization=$ORG" \
      | jq '.components | length')
  else
    PROJECT_EXISTS=$(curl -s -u "$SONAR_TOKEN:" \
      "$HOST_URL/api/projects/search?projects=$PROJECT_KEY" \
      | jq '.components | length')
  fi

  echo "Project exists: $PROJECT_EXISTS"

  if [[ "$PROJECT_EXISTS" == "0" ]]; then

    echo "Creating project $PROJECT_KEY"

    if [[ "$IS_SONARCLOUD" == true ]]; then

      curl -u "$SONAR_TOKEN:" \
      -X POST "$HOST_URL/api/projects/create" \
      -d "organization=$ORG" \
      -d "project=$PROJECT_KEY" \
      -d "name=$PROJECT_KEY"

    else
      echo " Project creation URL: $HOST_URL/api/projects/create?project=$PROJECT_KEY&name=$PROJECT_KEY"
      r=$(curl -u "$USER_TOKEN:" \
	      -X POST "$HOST_URL/api/projects/create?project=$PROJECT_KEY&name=$PROJECT_KEY&visibility=private") 

      echo "Project creation response: $r"

      echo "Permission call : $HOST_URL/api/permissions/add_user?login=$USER_NAME&projectKey=$PROJECT_KEY&permission=scan"

      p=$(curl -u "$SONAR_TOKEN:" \
	      -X POST "$HOST_URL/api/permissions/add_user?login=$USER_NAME&projectKey=$PROJECT_KEY&permission=scan")

      echo "Permission assignment response: $p"
    fi
  else
    echo "Project already exists"
  fi
}

########################################
# Install scanners
########################################
echo "Installing scanners..."

dotnet tool install --global dotnet-sonarscanner || true
export PATH="$PATH:$HOME/.dotnet/tools"

# install pytest 
pip install pytest || true

########################################
#install sonar-scanner
#########################################

echo "Installing SonarScanner CLI..."

SONAR_DIR="$HOME/.sonar-scanner"

if [ ! -d "$SONAR_DIR" ]; then
  mkdir -p "$SONAR_DIR"

  curl -sSLo /tmp/sonar-scanner.zip \
    https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip

  unzip -q /tmp/sonar-scanner.zip -d "$SONAR_DIR"

  mv $SONAR_DIR/sonar-scanner-* $SONAR_DIR/current
fi

export PATH="$SONAR_DIR/current/bin:$PATH"

echo "SonarScanner CLI version:"
sonar-scanner --version

########################################
which sonar-scanner || echo "sonar-scanner not found"

########################################
# Detect technologies
########################################

DOTNET_SOLUTIONS=$(find "$BASE_DIR" -name "*.sln" || true)
MAVEN_PROJECTS=$(find "$BASE_DIR" -name "pom.xml" || true)
NODE_PROJECTS=$(find "$BASE_DIR" -name "package.json" || true)
PY_PROJECTS=$(find "$BASE_DIR" -name "requirements.txt" || true)
GO_PROJECTS=$(find "$BASE_DIR" -name "go.mod" || true)

echo "Detected .NET solutions: $DOTNET_SOLUTIONS"
echo "Detected Maven projects: $MAVEN_PROJECTS"
echo "Detected NodeJS projects: $NODE_PROJECTS"
echo "Detected Python projects: $PY_PROJECTS"
echo "Detected Go projects: $GO_PROJECTS"

########################################
# Build stage
########################################

echo "====================================="
echo "Building monorepo projects"
echo "====================================="

build_dotnet() {
  # check for dotnet , if not install, throw error,
  for SLN in $DOTNET_SOLUTIONS; do
    DIR=$(dirname "$SLN")
    echo "Building .NET: $SLN"
    (
      cd "$DIR"
      dotnet restore "$SLN"
      dotnet build "$SLN"
      dotnet test "$SLN" || true
    ) &
  done
}

build_maven() {
  for POM in $MAVEN_PROJECTS; do
    DIR=$(dirname "$POM")
    echo "Building Maven: $POM"
    (
      cd "$DIR"
      mvn -B clean verify
    ) &
  done
}

build_node() {
  for PKG in $NODE_PROJECTS; do
    DIR=$(dirname "$PKG")
    echo "Building NodeJS: $PKG"
    (
      cd "$DIR"
      npm install
      npm test || true
    ) &
  done
}

build_python() {
  for REQ in $PY_PROJECTS; do
    DIR=$(dirname "$REQ")
    echo "Building Python: $REQ"
    (
      cd "$DIR"
      pip install -r requirements.txt || true
      pytest || true
    ) &
  done
}

build_go() {
  for MOD in $GO_PROJECTS; do
    DIR=$(dirname "$MOD")
    echo "Building Go: $MOD"
    (
      cd "$DIR"
      go mod tidy
      go test ./... || true
    ) &
  done
}

build_dotnet
build_maven
build_node
build_python
build_go

wait

########################################
# Create project
########################################
create_project_if_missing


#########################################
# comment for c code analysis, as it requires compile_commands.json file, we can enable it in future once we have a way to generate compile_commands.json file for c/c++ projects in monorepo, for now we can disable it to avoid scan failure due to missing compile_commands.json file

CFAMILY_OPTIONS=""

COMPILE_DB=$(find "$BASE_DIR" -name "compile_commands.json" | head -1)

if [[ -n "$COMPILE_DB" ]]; then
  echo "C/C++ compilation database detected: $COMPILE_DB"
  CFAMILY_OPTION="-Dsonar.cfamily.compile-commands=$COMPILE_DB"
else
  echo "No compilation database found. Disabling C/C++ analysis."

  CFAMILY_OPTION="-Dsonar.c.file.suffixes=- -Dsonar.cpp.file.suffixes=- -Dsonar.objc.file.suffixes=-"
fi
########################################

echo "CFAMILY_OPTION: $CFAMILY_OPTION"

########################################
# Run Sonar scan
########################################

echo "====================================="
echo "Running Sonar analysis"
echo "====================================="

echo "All details:"
echo "HOST_URL: $HOST_URL"
echo "PROJECT_KEY: $PROJECT_KEY"
echo "ORG: $ORG"
echo "IS_SONARCLOUD: $IS_SONARCLOUD"  
echo "CFAMILY_OPTION: $CFAMILY_OPTION"

SCANNER_OPTS=(
  -Dsonar.projectKey=$PROJECT_KEY
  -Dsonar.sources=$BASE_DIR
  -Dsonar.host.url=$HOST_URL
  -Dsonar.java.binaries=**/target/classes
  -Dsonar.exclusions=**/node_modules/**,**/.git/**,**/target/**,**/build/**,**/dist/**
)

if [ "$IS_SONARCLOUD" = "true" ]; then
  SCANNER_OPTS+=(-Dsonar.organization=$ORG)
  SCANNER_OPTS+=(-Dsonar.token=$USER_TOKEN)
else
  VERSION=$(curl -s $HOST_URL/api/server/version | cut -d. -f1)

  if [ "$VERSION" -ge 10 ]; then
    SCANNER_OPTS+=(-Dsonar.token=$USER_TOKEN)
  else
    SCANNER_OPTS+=(-Dsonar.login=$USER_TOKEN)
  fi
  
fi

if [ -n "$CFAMILY_OPTION" ]; then
  SCANNER_OPTS+=($CFAMILY_OPTION)
fi

echo "Running scanner..."
echo "sonar-scanner -X ${SCANNER_OPTS[*]}"


sonar-scanner "${SCANNER_OPTS[@]}"

echo "====================================="
echo "Sonar analysis completed"
echo "====================================="
