package egovframework.com.mtdata.database.web;

import egovframework.com.mtdata.config.dbConn.mySql.CreateYaml;
import egovframework.com.mtdata.database.service.DatabaseService;
import egovframework.com.mtdata.database.vo.*;
import egovframework.com.mtdata.schema.service.impl.DatabaseSchemaViewerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/api")
public class DatabaseConnController {

	/** Service */
	@Resource(name = "DatabaseService")
	private DatabaseService dbService;

	@Resource(name = "viService")
	private DatabaseSchemaViewerService viService;

	private static final Logger log = LoggerFactory.getLogger(DatabaseConnController.class);

	@RequestMapping("/insertDbConn.do")
	@Transactional(rollbackFor = Exception.class)
	public String insertDbConn(@ModelAttribute DatabaseInfoVO vo) throws Exception {

		/** 하단의 vo.setting은 임시설정으로, 사용자가 입력한 데이터를 vo객체에 받아올 것임 */
		vo.setSysId(1); // [inst_sys_info]테이블의 sysId를 참조하고 있음.sysId : 정보시스템 고유 아이디값
		vo.setDbConnUser("replica_user");
		vo.setDbConnPw("dpcPW12!@");
		vo.setDbConnPort(3306);
		vo.setDbConnIp("223.130.160.210");
		vo.setDbType("mysql");
		vo.setRegisterId("qkrrkdus@korea.kr"); // 이 값은 세션에서 가지고 올 것임

		try {
			// 기존 정보 여부 검증
			int check = dbService.checkDbConnInfo(vo);

			if (check < 1) {
				// 성공적으로 검증된 경우에 트랜잭션 시작
				int succ = dbService.insertDbConnInfo(vo);

				if (succ > 0) {
					DatabaseInfoVO infoVo = dbService.selectSysDb(vo);
					viService.selectSchema(infoVo);

					return "연결정보 저장 및 스키마 조회 성공";
				} else {
					// 오류 발생시 롤백
					throw new RuntimeException("연결정보 저장 실패");
				}
			} else {
				log.debug("====================================");
				log.debug("dbConnIp : '{}'에 대한 정보가 {}건 저장되어있습니다.", vo.getDbConnIp(), check);
				return "기존 입력된 정보가 존재함";
			}
		} catch (Exception e) {
			log.error("Exception {}", e);
			throw new RuntimeException(e.getMessage());
		}
	}

	@RequestMapping("/updateYaml.do")
	public void updateYaml(@ModelAttribute DatabaseInfoVO vo) {
		// 임시로 넣음 [해당 데이터는 databaseInfovo 에 담겨있을 것임]

		vo.setDbType("mysql");
		try {
			if ("mysql".equals(vo.getDbType())) {
				List<DatabaseInfoVO> mysqlInfoList = dbService.selectSysDbConnList(vo);

				CreateYaml yaml = new CreateYaml();
				yaml.createYaml(mysqlInfoList);

				log.info("========================================");
				log.info("yaml 파일 생성 성공");
			}
		} catch (Exception e) {
			log.error("Exception", e);
			throw new RuntimeException(e.getMessage());
		}
	}

	// DB관리 > 등록된 DB정보관리 리스트
	@GetMapping(value="/get/registerdDBInfoList.do")
	@ResponseBody
	public ResponseEntity<?> getRegisterdDBInfoList(DatabaseInfoVO databaseInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectRegisterdDBInfoList(databaseInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	// DB관리 > 등록된 DB정보관리 수정
	@PostMapping(value="/update/registerdDBInfoList.do")
	@ResponseBody
	public ResponseEntity<?> updateRegisterdDBInfoList(@RequestBody DatabaseInfoVO databaseInfoVO) {
		try{
			dbService.updateRegisterdDBInfoList(databaseInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}


	// DB관리 > 등록된 DB정보관리 삭제
	@PostMapping(value="/delete/registerdDBInfoList.do")
	@ResponseBody
	public ResponseEntity<?> deleteRegisterdDBInfoList(@RequestBody DatabaseInfoVO databaseInfoVO) {
		try{
			dbService.deleteRegisterdDBInfoList(databaseInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	// inst_db_conn_info 테이블 기본 CRUD
	@GetMapping(value="/get/instDbConnInfoList.do")
	@ResponseBody
	public ResponseEntity<?> getDbConnInfoList(DBConnInfoVO dbConnInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbConnInfoList(dbConnInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@GetMapping(value="/get/instDbConnInfo.do")
	@ResponseBody
	public ResponseEntity<?> getDbConnInfo(DBConnInfoVO dbConnInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbConnInfo(dbConnInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/insert/instDbConnInfo.do")
	@ResponseBody
	public ResponseEntity<?> insertDbConnInfo(@RequestBody DBConnInfoVO dbConnInfoVO) {
		try{

			dbService.insertInstDbConnInfo(dbConnInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/update/instDbConnInfo.do")
	@ResponseBody
	public ResponseEntity<?> updateDbConnInfo(@RequestBody DBConnInfoVO dbConnInfoVO) {
		try{

			dbService.updateInstDbConnInfo(dbConnInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/delete/instDbConnInfo.do")
	@ResponseBody
	public ResponseEntity<?> deleteDbConnInfo(@RequestBody DBConnInfoVO dbConnInfoVO) {
		try{

			dbService.deleteInstDbConnInfo(dbConnInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	// inst_db_info 테이블 기본 CRUD
	@GetMapping(value="/get/instDbInfoList.do")
	@ResponseBody
	public ResponseEntity<?> getDbInfoList(DBInfoVO dbInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbInfoList(dbInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@GetMapping(value="/get/instDbInfo.do")
	@ResponseBody
	public ResponseEntity<?> getDbInfo(DBInfoVO dbInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbInfo(dbInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/insert/instDbInfo.do")
	@ResponseBody
	public ResponseEntity<?> insertDbInfo(@RequestBody DBInfoVO dbInfoVO) {
		try{

			dbService.insertInstDbInfo(dbInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/update/instDbInfo.do")
	@ResponseBody
	public ResponseEntity<?> updateDbInfo(@RequestBody DBInfoVO dbInfoVO) {
		try{

			dbService.updateInstDbInfo(dbInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/delete/instDbInfo.do")
	@ResponseBody
	public ResponseEntity<?> deleteDbInfo(@RequestBody DBInfoVO dbInfoVO) {
		try{

			dbService.deleteInstDbInfo(dbInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	// inst_db_tbl_info 테이블 기본 CRUD
	@GetMapping(value="/get/instDbTblInfoList.do")
	@ResponseBody
	public ResponseEntity<?> getDbTblInfoList(DBTblInfoVO dbTblInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbTblInfoList(dbTblInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@GetMapping(value="/get/instDbTblInfo.do")
	@ResponseBody
	public ResponseEntity<?> getDbTblInfo(DBTblInfoVO dbTblInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbTblInfo(dbTblInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/insert/instDbTblInfo.do")
	@ResponseBody
	public ResponseEntity<?> insertDbTblInfo(@RequestBody DBTblInfoVO dbTblInfoVO) {
		try{

			dbService.insertInstDbTblInfo(dbTblInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/update/instDbTblInfo.do")
	@ResponseBody
	public ResponseEntity<?> updateDbTblInfo(@RequestBody DBTblInfoVO dbTblInfoVO) {
		try{

			dbService.updateInstDbTblInfo(dbTblInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/delete/instDbTblInfo.do")
	@ResponseBody
	public ResponseEntity<?> deleteDbTblInfo(@RequestBody DBTblInfoVO dbTblInfoVO) {
		try{

			dbService.deleteInstDbTblInfo(dbTblInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	// inst_tbl_col_info 테이블 기본 CRUD
	@GetMapping(value="/get/instDbTblColInfoList.do")
	@ResponseBody
	public ResponseEntity<?> getDbTblColInfoList(DBTblColInfoVO dbTblColInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbTblColInfoList(dbTblColInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}


	@GetMapping(value="/get/instDbTblColInfo.do")
	@ResponseBody
	public ResponseEntity<?> getDbTblColInfo(DBTblColInfoVO dbTblColInfoVO) {
		try{
			return ResponseEntity.ok().body(dbService.selectInstDbTblColInfo(dbTblColInfoVO));
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/insert/instDbTblColInfo.do")
	@ResponseBody
	public ResponseEntity<?> insertDbTblColInfo(@RequestBody DBTblColInfoVO dbTblColInfoVO) {
		try{

			dbService.insertInstDbTblColInfo(dbTblColInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/update/instDbTblColInfo.do")
	@ResponseBody
	public ResponseEntity<?> updateDbTblColInfo(@RequestBody DBTblColInfoVO dbTblColInfoVO) {
		try{

			dbService.updateInstDbTblColInfo(dbTblColInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}

	@PostMapping(value="/delete/instDbTblColInfo.do")
	@ResponseBody
	public ResponseEntity<?> deleteDbTblColInfo(@RequestBody DBTblColInfoVO dbTblColInfoVO) {
		try{

			dbService.deleteInstDbTblColInfo(dbTblColInfoVO);
			return ResponseEntity.ok().build();
		} catch(Exception e){
			log.error("Exception", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
		}
	}
}
