#!/bin/bash

DB=""        # 실제 데이터베이스 이름으로 변경
USER="postgres"          # 실제 PostgreSQL 사용자명으로 변경
SCHEMA="public"           # 스키마 이름
TABLE=""      # 생성할 테이블 이름

SRID_ORI=5186             # 원본 좌표계
SRID_NEW=0                # 변환 좌표계 (0이면 좌표변환 안함)
CHARSET="EUC-KR"          # 문자 인코딩

SHP_DIR="./"     # shp 파일들이 있는 디렉토리 경로
MAX_JOBS=8                # 병렬 작업 수 (시스템 성능에 따라 조정)

# 로그 파일 설정
LOG_DIR="./"  # 로그 디렉토리 (필요시 경로 변경)
mkdir -p "$LOG_DIR"  # 로그 디렉토리가 없으면 생성
LOG_FILE="$LOG_DIR/shp_import_$(date '+%Y%m%d_%H%M%S').log"

# 로그 함수 정의
logger() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 시작 시간 기록
START_TIME=$(date '+%Y-%m-%d %H:%M:%S')
START_TIMESTAMP=$(date +%s)


# SHP 디렉토리 및 파일 존재 확인
if [ ! -d "$SHP_DIR" ]; then
    logger "❌ 오류: SHP 디렉토리가 존재하지 않습니다: $SHP_DIR"
    exit 1
fi

SHP_COUNT=$(find "$SHP_DIR" -name "*.shp" | wc -l)
if [ $SHP_COUNT -eq 0 ]; then
    logger "❌ 오류: SHP 파일이 없습니다: $SHP_DIR"
    exit 1
fi
logger "📁 발견된 SHP 파일 수: $SHP_COUNT개"

# PostgreSQL 연결 테스트
if ! psql -U "$USER" -d "$DB" -c "SELECT 1;" >/dev/null 2>&1; then
    logger "❌ 오류: PostgreSQL 연결 실패. 데이터베이스 연결을 확인해주세요."
    exit 1
fi
logger "✅ PostgreSQL 연결 성공"

# 좌표계 설정 확인 및 로깅
if [ "$SRID_NEW" -ne 0 ]; then
    logger "🗺️ 좌표변환 모드: $SRID_ORI → $SRID_NEW"
else
    logger "🗺️ 원본좌표계 사용: $SRID_ORI"
fi

logger "=================================="
logger "🚀 Import 시작: $START_TIME"
logger "=================================="

# 테이블 존재 여부 확인
logger "🔍 테이블 존재 여부 확인 중: $SCHEMA.$TABLE"
TABLE_EXISTS=$(psql -U "$USER" -d "$DB" -t -c "SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = '$SCHEMA' AND tablename = '$TABLE');" 2>/dev/null | tail -1 | tr -d ' \n\r')

if [[ "$TABLE_EXISTS" == *"true"* ]] || [[ "$TABLE_EXISTS" == "true" ]]; then
    logger "📋 테이블 $SCHEMA.$TABLE이 이미 존재합니다. Append 모드로 진행합니다."
    FIRST=""
else
    logger "📋 테이블 $SCHEMA.$TABLE이 존재하지 않습니다. 새로 생성합니다."
    # 1. 테이블 먼저 생성 (첫 번째 .shp 기준, 인덱스 없이)
    FIRST=$(find "$SHP_DIR" -name "*.shp" | head -n 1)
    logger "Creating table $SCHEMA.$TABLE using $FIRST (without index)"
    
    # 좌표변환 여부에 따라 shp2pgsql 명령어 결정
    if [ "$SRID_NEW" -ne 0 ]; then
        OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW "$FIRST" $SCHEMA.$TABLE | psql -U "$USER" -d "$DB" 2>&1)
    else
        OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI "$FIRST" $SCHEMA.$TABLE | psql -U "$USER" -d "$DB" 2>&1)
    fi
    EXIT_CODE=$?

    if [ $EXIT_CODE -eq 0 ]; then
        logger "✅ Table creation completed successfully"
    else
        logger "❌ Table creation failed"
        echo "$OUTPUT" >> "$LOG_FILE"
        exit 1
    fi
fi

# 2. 병렬로 나머지 파일 append (shp2pgsql -a)
function import_append() {
  SHP="$1"
  BASENAME=$(basename "$SHP")
  
  # 테이블이 새로 생성된 경우: 첫 번째 파일은 건너뛰기
  if [[ -n "$FIRST" ]] && [[ "$SHP" == "$FIRST" ]]; then
    logger "⏭️ Skipping $BASENAME (already processed during table creation)"
    return
  fi
  
  logger "Appending $BASENAME"
  
  # 좌표변환 여부에 따라 shp2pgsql 명령어 결정
  if [ "$SRID_NEW" -ne 0 ]; then
      OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI:$SRID_NEW -a "$SHP" $SCHEMA.$TABLE | psql -U "$USER" -d "$DB" 2>&1)
  else
      OUTPUT=$(shp2pgsql -W "$CHARSET" -s $SRID_ORI -a "$SHP" $SCHEMA.$TABLE | psql -U "$USER" -d "$DB" 2>&1)
  fi
  EXIT_CODE=$?
  
  if [ $EXIT_CODE -eq 0 ]; then
      logger "✅ $BASENAME appended successfully"
  else
      logger "❌ Failed to append $BASENAME"
      echo "$OUTPUT" >> "$LOG_FILE"
  fi
}

# job control 함수
function wait_for_jobs() {
  while (( $(jobs -rp | wc -l) >= MAX_JOBS )); do
    sleep 1
  done
}

# 병렬 실행
for shp in "$SHP_DIR"/*.shp; do
  wait_for_jobs
  import_append "$shp" &
done

wait

# 데이터 입력 완료 시간 기록
DATA_END_TIME=$(date '+%Y-%m-%d %H:%M:%S')
DATA_END_TIMESTAMP=$(date +%s)
DATA_DURATION=$((DATA_END_TIMESTAMP - START_TIMESTAMP))

# 데이터 입력 시간을 시:분:초 형식으로 변환
DATA_HOURS=$((DATA_DURATION / 3600))
DATA_MINUTES=$(((DATA_DURATION % 3600) / 60))
DATA_SECONDS=$((DATA_DURATION % 60))

# 1보다 작으면 0으로 표시
if [ $DATA_HOURS -lt 1 ]; then DATA_HOURS=0; fi
if [ $DATA_MINUTES -lt 1 ]; then DATA_MINUTES=0; fi

logger "=================================="
logger "📊 데이터 입력 완료: $DATA_END_TIME"
logger "📊 데이터 입력 소요시간: ${DATA_HOURS}시간 ${DATA_MINUTES}분 ${DATA_SECONDS}초"
logger "=================================="

# 3. (선택) 인덱스 재생성 (권장: 한 번에 생성)
INDEX_START_TIME=$(date '+%Y-%m-%d %H:%M:%S')
INDEX_START_TIMESTAMP=$(date +%s)

logger "🔍 공간 인덱스 생성 시작: $INDEX_START_TIME"

# 공간 인덱스 생성 (PostGIS 확장이 활성화되어 있어야 함)
psql -U "$USER" -d "$DB" -c "CREATE INDEX IF NOT EXISTS ${TABLE}_geom_idx ON $SCHEMA.$TABLE USING GIST (geom);" >/dev/null 2>&1
INDEX_EXIT_CODE=$?

if [ $INDEX_EXIT_CODE -eq 0 ]; then
    logger "✅ Spatial index created successfully"
else
    logger "❌ Failed to create spatial index"
    logger "⚠️ PostGIS 확장이 활성화되어 있는지 확인하세요: CREATE EXTENSION IF NOT EXISTS postgis;"
fi

# 인덱스 재생성 완료 시간 기록
INDEX_END_TIME=$(date '+%Y-%m-%d %H:%M:%S')
INDEX_END_TIMESTAMP=$(date +%s)
INDEX_DURATION=$((INDEX_END_TIMESTAMP - INDEX_START_TIMESTAMP))

# 인덱스 재생성 시간을 시:분:초 형식으로 변환
INDEX_HOURS=$((INDEX_DURATION / 3600))
INDEX_MINUTES=$(((INDEX_DURATION % 3600) / 60))
INDEX_SECONDS=$((INDEX_DURATION % 60))

# 1보다 작으면 0으로 표시
if [ $INDEX_HOURS -lt 1 ]; then INDEX_HOURS=0; fi
if [ $INDEX_MINUTES -lt 1 ]; then INDEX_MINUTES=0; fi

# 전체 종료 시간 및 소요 시간 계산
END_TIME=$(date '+%Y-%m-%d %H:%M:%S')
END_TIMESTAMP=$(date +%s)
TOTAL_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))

# 전체 시간을 시:분:초 형식으로 변환
TOTAL_HOURS=$((TOTAL_DURATION / 3600))
TOTAL_MINUTES=$(((TOTAL_DURATION % 3600) / 60))
TOTAL_SECONDS=$((TOTAL_DURATION % 60))

# 1보다 작으면 0으로 표시
if [ $TOTAL_HOURS -lt 1 ]; then TOTAL_HOURS=0; fi
if [ $TOTAL_MINUTES -lt 1 ]; then TOTAL_MINUTES=0; fi

logger "=================================="
logger "✅ 전체 작업 완료: $END_TIME"
logger "📊 전체 소요시간: ${TOTAL_HOURS}시간 ${TOTAL_MINUTES}분 ${TOTAL_SECONDS}초"
logger "📋 상세 요약:"
logger "   - 전체 시작시간: $START_TIME"
logger "   - 데이터 입력 완료: $DATA_END_TIME (소요: ${DATA_HOURS}시간 ${DATA_MINUTES}분 ${DATA_SECONDS}초)"
logger "   - 공간 인덱스 생성 시작: $INDEX_START_TIME"
logger "   - 공간 인덱스 생성 완료: $INDEX_END_TIME (소요: ${INDEX_HOURS}시간 ${INDEX_MINUTES}분 ${INDEX_SECONDS}초)"
logger "   - 전체 종료시간: $END_TIME"
logger "   - 대상테이블: $SCHEMA.$TABLE"
if [ "$SRID_NEW" -ne 0 ]; then
    logger "   - 좌표계: $SRID_ORI → $SRID_NEW (변환됨)"
else
    logger "   - 좌표계: $SRID_ORI (원본)"
fi
logger "📊 데이터 처리 완료"
logger "=================================="
logger "로그 파일: $LOG_FILE"