#!/bin/bash

# Script to create the Fam-tree project structure

# Set project name
project_name="fam-tree"
root_dir="."

# Set environment variables for your project
export PROJECT_ENV_VAR1="value1"
export PROJECT_ENV_VAR2="value2"

# Set logs directory
logs_directory="$root_dir/logs"

# Feature Flags
feature_git=0
feature_docker=0

# Error flag
error_flag=0

# Function to display messages to both console and log file
log_error() {
  echo "E: $(date +"%Y-%m-%d %H:%M:%S") - $1"
}
log_message() {
  echo "I: $(date +"%Y-%m-%d %H:%M:%S") - $1"
}

# Function to create a directory if it doesn't exist
create_directory() {
  if [ ! -d "$1" ]; then
    mkdir -p "$1"
    if [ $? -ne 0 ]; then
      log_error "Error: Failed to create directory '$1'" >&2
      error_flag=1
    else
      log_message "Created directory: $1"
    fi
  else
    log_message "Directory exists. Skipped: $1"
  fi
}

# Function to create a file if it doesn't exist
create_file() {
  if [ ! -f "$1" ]; then
    touch "$1"
    if [ $? -ne 0 ]; then
      log_error "Error: Failed to create file '$1'" >&2
      error_flag=1
    else
      log_message "Created file: $1"
    fi
  else
    log_message "File exists. Skipped: $1"
  fi
}

install_dependency() {
  local dependency="$1"

  if ! command -v "$dependency" &> /dev/null; then
    echo "Installing $dependency..."
    case "$dependency" in
      "docker")
	# Install Docker using the official scrip
	curl -fsSL https://get.docker.com -o get-docker.sh
	sudo sh get-docker.sh
	rm get-docker.sh
	;;
      *)
	# For other dependencies, use your package manager
	# Add more conditions for different package managers (e.g., apt, yum)
	echo "Please install $dependency manually."
	error_flag=1
	;;
    esac
  fi
}

check_tool_exists() {
  local tool_name=$1
  command -v "$tool_name" >/dev/null 2>&1
  return $?
}

if check_tool_exists "git"; then
  feature_git=1
fi

if check_tool_exists "docker"; then
  feature_docker=1
fi

# Function to generate GitLab CI configuration
generate_gitlab_ci() {
  local gitlab_ci_file=".gitlab-ci.yml"
  cat <<EOL > "$gitlab_ci_file"
stages:
	- build
	- test
	- deploy

variables:
	DOCKER_COMPOSE_VERSION: "1.27.4"

before_script:
	- docker --version
	- docker-compose --version

services:
	- docker:$DOCKER_COMPOSE_VERSION

build:
	stage: build
	script:
		- docker-compose build

test:
	stage: test
	script:
		- docker-compose run --rm backend /your/test/command

deploy:
	stage: deploy
	script:
		- echo "Deploy your application here"
EOL

echo "GitLab CI file created: $gitlab_ci_file"
}


# Create logs directory
create_directory "$logs_directory"

# Create log file with timestamp
log_file="$logs_directory/$(date +"%Y%m%d%H%M%S").log"
touch "$log_file"

# Redirect all subsequent output to the log file
exec 3>&1 4>&2 1>>"$log_file" 2>&1


# Display welcome message in the log
log_message "Creating project structure for $project_name"

# Create backend directory
create_directory "$root_dir/backend"
create_file "$root_dir/backend/main.go"

# Create API directory
create_directory "$root_dir/backend/api"
create_file "$root_dir/backend/api/family-tree.proto"

# Create database directory
create_directory "$root_dir/backend/database"
create_directory "$root_dir/backend/database/migrations"

# Create cmd directory for server configurations
create_directory "$root_dir/backend/cmd"
create_directory "$root_dir/backend/cmd/server"
create_file "$root_dir/backend/cmd/server/config.yaml"
create_file "$root_dir/backend/cmd/server/start.sh"
create_file "$root_dir/backend/cmd/server/stop.sh"

# Create frontend directory
create_directory "$root_dir/frontend"
create_directory "$root_dir/frontend/src"
create_directory "$root_dir/frontend/src/components"
create_directory "$root_dir/frontend/src/services"

# Create proto directory for shared .proto definitions
create_directory "$root_dir/proto"
create_file "$root_dir/proto/family-tree.proto"

# Create nginx directory
create_directory "$root_dir/nginx"
create_file "$root_dir/nginx/nginx.conf"

# Create backend directory
create_directory "$root_dir/backend"
create_file "$root_dir/backend/dockerfile"

# Create frontend directory
create_directory "$root_dir/frontend"
create_file "$root_dir/frontend/dockerfile"

# Create docker-compose.yml for Docker Compose configuration
create_file "$root_dir/docker-compose.yml"

# Create scripts directory for setup, start, and stop scripts
create_directory "$root_dir/scripts"
create_file "$root_dir/scripts/setup.sh"
create_file "$root_dir/scripts/start.sh"
create_file "$root_dir/scripts/stop.sh"

# Create docs directory for documentation
create_directory "$root_dir/docs"
create_file "$root_dir/docs/api.md"
create_file "$root_dir/docs/database.md"

# Create cron directory for automated scheduled actions
create_directory "$root_dir/cron"
create_file "$root_dir/cron/cronjobs"
create_file "$root_dir/cron/tasks"

# Create tests directory for automated tests
create_directory "$root_dir/tests"

# Create ci-cd directory for GitLab CI/CD configuration
create_directory "$root_dir/ci-cd"
create_file "$root_dir/ci-cd/gitlab-ci.yml"

# Create config directory for application settings
create_directory "$root_dir/config"
create_file "$root_dir/config/config.yaml"

# Create README.md for project documentation
create_file "$root_dir/README.md"

# Create .gitignore for Git ignore file
create_file "$root_dir/.gitignore"
# Function to create a gitignore file
create_gitignore() {
  cat <<EOL > .gitignore
# Ignore logs
logs/

# Ignore compiled binaries
*.exe
*.dll
*.out

# Ignore user-specific files
.idea/
.vscode/

# Ignore system files
.DS_Store
Thumbs.db

# Ignore node modules
node_modules/

# Ignore compiled TypeScript
*.js
*.js.map

# Ignore Go binary
*.go

# Ignore Docker artifacts
dockerfile.*
docker-compose.yml

# Ignore dependencies
vendor/

# Ignore compiled Python files
*.pyc
__pycache__/

# Ignore compiled Java files
*.class

# Ignore temporary files
*.tmp

# Ignore editor backup files
*~
*.swp
*.swo
*.swn
*.swm
*.swl

# Ignore environment variables file
.env

# Ignore build artifacts
build/
dist/

# Ignore database migrations
database/migrations/*.sql
EOL
}

initialize_git_repository() {
  if [ "$feature_git" -ne 0 ]; then
    if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1;
    then
      log_message "Git repo already enabled"
    else
      git init --initial-branch=main
      if [ $? -ne 0 ]; then
	log_error "Error: Failed to initialize Git repository" >&2
	error_flag=1
      else
	git add -A
	git commit -m "Initial commit for project: $project_name"
      fi
    fi
  else
    log_message "Git not enabled"
  fi
}

# Function to create a pre-commit hook
create_pre_commit_hook() {
  if [ "$feature_git" -ne 0 ]; then
    local pre_commit_hook=".git/hooks/pre-commit"
    local hook_script="#!/bin/bash\n\n# This script runs before every commit to perform linting, formatting, or other checks\n# Add your checks or commands here\n\n# Example: Run a linter\n# lint_command=\"your-linter-command\"\n# \$lint_command\n\n# Example: Run a formatter\n# format_command=\"your-formatter-command\"\n# \$format_command\n\n# If any command fails, the commit will be aborted\n"

create_file "$pre_commit_hook"
echo "$hook_script" > "$pre_commit_hook"
chmod +x "$pre_commit_hook"
  fi
}

# Check for errors
if [ "$error_flag" -eq 1 ]; then
  echo "Error: One or more errors occurred during script execution. See the log for details." >&2
  exit 1
fi

# Function to create README with a basic structure
create_readme() {
  local readme_file="README.md"
  local readme_content="# $project_name\nThis is a basic README file for the project."
  create_file "$readme_file"
  echo "$readme_content" > "$readme_file"
}

dependencies=("git" "docker")
for dep in "${dependencies[@]}"; do 
  echo "$dep"
done

# Create gitignore file
create_gitignore
initialize_git_repository
create_readme
generate_gitlab_ci

# Display success message in the log
echo "Gitignore file created successfully"

# Display success message in the log
log_message "Project structure for $project_name created successfully"

# Restore default output and close the log file
exec 1>&3 2>&4
exec 3>&- 4>&-

# Display log file path
echo "Log file created at: $log_file"
