#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// EMPLOYEES 테이블 구조 기반으로 재정의
struct EMPLOYEE {
	char emp_id[10];	// EMPL_ID
	char full_name[30];	// FULL_NAME
	char hire_date[15];	// HIRE_DATE
	char married[5];	// MARRIED
	char gender[5];	// GENDER
	int on_leave;	// 재직 상태(0: 재직 중, 1 : 휴직/퇴사)
};
typedef struct EMPLOYEE EMPLOYEE;

// 함수 프로토타입 (변동 없음)
int print_all_employees(EMPLOYEE* emp_list, int total_num_emp);
int print_employee_detail(EMPLOYEE* emp_list, int total_num_emp, char* target_id); // 💡 상세 조회 함수 수정

// 직원 정보 출력 헬퍼 함수 (변동 없음)
void display_employee_info(EMPLOYEE emp, int detail_mode);

// 문자열 비교 함수 (변동 없음)
char compare(char* str1, char* str2) {
	while (*str1 && *str2) {
		if (*str1 != *str2) {
			return 0;
		}
		str1++;
		str2++;
	}
	if (*str1 == '\\0' && *str2 == '\\0') return 1;
	return 0;
}

// -------------------------------------------------------------
// * 직원 정보 출력 헬퍼 함수 구현 * (변동 없음)
// -------------------------------------------------------------
void display_employee_info(EMPLOYEE emp, int detail_mode) {
	// ... (이전 코드와 동일)
	if (detail_mode == 0) {
		printf("%-10s // %-20s // %s\\n",
			emp.emp_id, emp.full_name,
			(emp.on_leave == 0) ? "재직 중" : "휴직/퇴사");
	}
	else {
		printf("\\n--- 직원 상세 정보 ---\\n");
		printf("  - 사번 (EMP_ID)  : %s\\n", emp.emp_id);
		printf("  - 이름 (FULL_NAME): %s\\n", emp.full_name);
		printf("  - 입사일 (HIRE_DATE): %s\\n", emp.hire_date);
		printf("  - 결혼 여부     : %s\\n", emp.married);
		printf("  - 성별 (GENDER) : %s\\n", emp.gender);
		printf("  - 재직 상태     : %s\\n", (emp.on_leave == 0) ? "재직 중" : "휴직/퇴사");
		printf("----------------------\\n");
	}
}

// -------------------------------------------------------------
// * 1. 전체 목록 조회 기능 구현 * (변동 없음)
// -------------------------------------------------------------
int print_all_employees(EMPLOYEE* emp_list, int total_num_emp) {
	if (total_num_emp == 0) {
		printf("등록된 직원 정보가 없습니다.\\n");
		return 0;
	}

	printf("\\n============================================\\n");
	printf("     ⭐ 전체 직원 목록 (간략 보기) ⭐\\n");
	printf("============================================\\n");
	printf("%-10s // %-20s // %s\\n", "사번", "이름", "상태");
	printf("--------------------------------------------\\n");

	for (int i = 0; i < total_num_emp; i++) {
		display_employee_info(emp_list[i], 0);
	}
	printf("============================================\\n");
	return 0;
}

// -------------------------------------------------------------
// * 2. 특정 사원 상세 정보 출력 기능 구현 (수정) *
// -------------------------------------------------------------
// 💡 함수 시그니처 수정: 사용자 입력을 main에서 받아와 바로 출력
int print_employee_detail(EMPLOYEE* emp_list, int total_num_emp, char* target_id) {

	if (total_num_emp == 0) {
		printf("등록된 직원 정보가 없습니다. \\n");
		return 0;
	}

	printf("\\n--- 사번 %s 상세 정보 조회 ---\\n", target_id); // 💡 어떤 사번을 조회하는지 표시

	for (int i = 0; i < total_num_emp; i++) {
		if (compare(emp_list[i].emp_id, target_id)) {
			display_employee_info(emp_list[i], 1);
			return 0;
		}
	}

	printf("\\n 사번 [%s]에 해당하는 직원을 찾을 수 없습니다.\\n", target_id);
	return -1;
}

// -------------------------------------------------------------
// * Main 함수 (조회 기능 즉시 실행) *
// -------------------------------------------------------------
int main() {
	int num_total_emp = 0;
	int max_employees = 5;
	EMPLOYEE* emp_list;

	emp_list = (EMPLOYEE*)malloc(sizeof(EMPLOYEE) * max_employees);
	if (emp_list == NULL) return 1;

	// --- ⭐ 테스트를 위한 더미 데이터 등록 ⭐ --- (변동 없음)
	strcpy(emp_list[0].emp_id, "A001");
	strcpy(emp_list[0].full_name, "김철수");
	strcpy(emp_list[0].hire_date, "2020-03-01");
	strcpy(emp_list[0].married, "YES");
	strcpy(emp_list[0].gender, "M");
	emp_list[0].on_leave = 0;
	num_total_emp++;

	strcpy(emp_list[1].emp_id, "B007");
	strcpy(emp_list[1].full_name, "이영희");
	strcpy(emp_list[1].hire_date, "2022-09-15");
	strcpy(emp_list[1].married, "NO");
	strcpy(emp_list[1].gender, "W");
	emp_list[1].on_leave = 1;
	num_total_emp++;
	// --------------------------------------------

	// 💡 1. 전체 목록 조회 기능 실행
	print_all_employees(emp_list, num_total_emp);

	// 💡 2. 특정 사원 상세 정보 출력 기능 실행 (사번 'A001' 즉시 조회)
	printf("\\n\\n--------------------------------------------\\n");
	printf("         🎯 특정 사원 정보 즉시 조회\\n");
	print_employee_detail(emp_list, num_total_emp, "A001");
	printf("--------------------------------------------\\n");

	// 💡 3. 프로그램 종료
	printf("\\n프로그램을 종료합니다.\\n");

	free(emp_list);
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlca.h> // 💡 Pro*C: SQL 통신 영역 헤더

// -------------------------------------------------------------
// 💡 Pro*C: SQLCA (SQL Communication Area) 선언
// DB 작업 상태와 오류 정보를 담는 구조체입니다.
// -------------------------------------------------------------
EXEC SQL INCLUDE SQLCA;

// -------------------------------------------------------------
// 💡 Pro*C: Host Variable (C 변수) 선언 섹션
// SQL 문에서 사용할 C 변수와 구조체를 선언합니다.
// -------------------------------------------------------------
EXEC SQL BEGIN DECLARE SECTION;

// DB 연결 정보
char db_user[] = "scott";
char db_pass[] = "tiger";
char db_sid[] = "dev"; // 👈 DB 인스턴스 이름 (환경에 맞게 수정 필요)

// DB 테이블 구조체 (EMPLOYEES 테이블 컬럼 반영)
struct EMPLOYEE_T {
	char emp_id[6];	    // EMPL_ID (VARCHAR2(5) + NULL 종료 문자)
	char full_name[31];	// FULL_NAME (VARCHAR2(30) + NULL 종료 문자)
	char hire_date[9];	// HIRE_DATE (VARCHAR2(8) + NULL 종료 문자)
	char married[2];	// MARRIED (VARCHAR2(1) + NULL 종료 문자)
	int salary;         // SALARY (NUMBER(10))
	char gender[2];	    // GENDER (VARCHAR2(1) + NULL 종료 문자)
};
typedef struct EMPLOYEE_T EMPLOYEE_T;

// 상세 조회 시 사용할 입력 변수
char search_id[6];

EXEC SQL END DECLARE SECTION;

// -------------------------------------------------------------
// * DB와 무관한 헬퍼 함수 정의 (Pro*C 파일에 포함) *
// -------------------------------------------------------------

// 직원 정보 출력 헬퍼 함수 (DB 구조체에 맞게 수정)
void display_employee_info(EMPLOYEE_T emp, int detail_mode) {
	// DB 구조체에는 on_leave가 없으므로 재직 중으로 가정하고 출력
	char on_leave_status[] = "Working"; 
    
	if (detail_mode == 0) {
		printf("%-10s // %-20s // %s\\n",
			emp.emp_id, emp.full_name, on_leave_status);
	}
	else {
		printf("\\n--- 직원 상세 정보 ---\\n");
		printf("  - 사번 (EMP_ID)    : %s\\n", emp.emp_id);
		printf("  - 이름 (FULL_NAME)  : %s\\n", emp.full_name);
		printf("  - 입사일 (HIRE_DATE): %s\\n", emp.hire_date);
		printf("  - 결혼 여부       : %s\\n", emp.married);
		printf("  - 성별 (GENDER)   : %s\\n", emp.gender);
		printf("  - 연봉 (SALARY)   : %d\\n", emp.salary); // 💡 SALARY 추가
		printf("  - 재직 상태       : %s\\n", on_leave_status);
		printf("----------------------\\n");
	}
}

// -------------------------------------------------------------
// * 1. DB 연결/해제 함수 구현 *
// -------------------------------------------------------------

void connect_db() {
    // SCOTT/TIGER@dev로 접속 시도
    EXEC SQL CONNECT :db_user IDENTIFIED BY :db_pass USING :db_sid; 
    
    if (sqlca.sqlcode != 0) {
        printf("🚨 DB 연결 실패 (SQLCODE: %d): %s\\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        exit(1);
    } else {
        printf("✅ DB 연결 성공: %s/%s@%s\\n", db_user, db_pass, db_sid);
    }
}

void disconnect_db() {
    EXEC SQL COMMIT WORK RELEASE; // 작업 확정 및 연결 해제
    printf("DB 연결 해제 완료.\\n");
}

// -------------------------------------------------------------
// * 2. 전체 목록 조회 기능 구현 (DB 연결) *
// -------------------------------------------------------------
int print_all_employees() {
    
    // 💡 커서 선언: DB에서 조회할 항목 지정
    EXEC SQL DECLARE emp_cursor CURSOR FOR
        SELECT EMPL_ID, FULL_NAME, HIRE_DATE, MARRIED, GENDER, SALARY 
        FROM EMPLOYEES
        ORDER BY EMPL_ID;

    EXEC SQL OPEN emp_cursor;
    
    printf("\\n============================================\\n");
    printf("     ⭐ DB에서 가져온 전체 직원 목록 ⭐\\n");
    printf("============================================\\n");
    printf("%-10s // %-20s // %s\\n", "사번", "이름", "상태");
    printf("--------------------------------------------\\n");

    EMPLOYEE_T current_emp; // 데이터를 담을 구조체
    int found_count = 0;
    
    while (1) {
        // 💡 FETCH: 커서에서 데이터를 가져와 C 구조체 변수에 담습니다.
        EXEC SQL FETCH emp_cursor INTO 
            :current_emp.emp_id, :current_emp.full_name, :current_emp.hire_date, 
            :current_emp.married, :current_emp.gender, :current_emp.salary;

        if (sqlca.sqlcode == 1403) break; // 1403: Data Not Found (조회 완료)
        if (sqlca.sqlcode != 0) {
            printf("🚨 데이터 조회 오류 (SQLCODE: %d): %s\\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
            break;
        }

        display_employee_info(current_emp, 0);
        found_count++;
    }
    
    EXEC SQL CLOSE emp_cursor;
    
    printf("============================================\\n");
    printf("총 %d명의 직원을 DB에서 조회했습니다.\\n", found_count);
    
    return 0;
}

// -------------------------------------------------------------
// * 3. 특정 사원 상세 정보 출력 기능 구현 (DB 연결) *
// -------------------------------------------------------------
int print_employee_detail() {
    EMPLOYEE_T detail_emp; // 상세 정보를 담을 구조체

	printf("조회할 사원의 사번(EMP_ID)을 입력하세요: ");
    // 💡 사번을 C 변수에 입력받습니다.
	scanf("%s", search_id); 
    
    // 💡 SELECT INTO: 단일 행 데이터를 조회할 때 사용
    EXEC SQL SELECT EMPL_ID, FULL_NAME, HIRE_DATE, MARRIED, GENDER, SALARY 
        INTO :detail_emp.emp_id, :detail_emp.full_name, :detail_emp.hire_date, 
             :detail_emp.married, :detail_emp.gender, :detail_emp.salary
        FROM EMPLOYEES
        WHERE EMPL_ID = :search_id; // C 변수(:search_id)를 조건으로 사용

    if (sqlca.sqlcode == 1403) {
        printf("\\n ❌ 사번 [%s]에 해당하는 직원을 찾을 수 없습니다.\\n", search_id);
        return -1;
    } else if (sqlca.sqlcode != 0) {
        printf("🚨 상세 조회 오류 (SQLCODE: %d): %s\\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
        return -1;
    }

    // 데이터가 성공적으로 조회되면 상세 정보 출력
    display_employee_info(detail_emp, 1);
    return 0;
}

// -------------------------------------------------------------
// * Main 함수 (DB 연결 및 조회 실행) *
// -------------------------------------------------------------
int main() {
    
    connect_db(); // DB 연결
    
    // 1. 전체 목록 조회 기능 실행 (DB에서 직접)
	print_all_employees(); 

    // 2. 특정 사원 상세 정보 출력 기능 실행 (DB에서 직접)
    printf("\\n\\n--------------------------------------------\\n");
    printf("         🎯 특정 사원 정보 상세 조회\\n");
	print_employee_detail();
    printf("--------------------------------------------\\n");

    disconnect_db(); // DB 연결 해제
    
    return 0;
}