Coverage Summary for Class: LogxFileSession (kr.open.library.simple_ui.core.logcat.internal.writer)

Class Class, % Method, % Branch, % Line, % Instruction, %
LogxFileSession 100% (1/1) 77.8% (7/9) 30% (6/20) 60% (24/40) 54.6% (112/205)


 package kr.open.library.simple_ui.core.logcat.internal.writer
 
 import kr.open.library.simple_ui.core.extensions.trycatch.safeCatch
 import kr.open.library.simple_ui.core.logcat.config.LogStorageType
 import kr.open.library.simple_ui.core.logcat.internal.common.LogxTimeUtils
 import java.io.BufferedWriter
 import java.io.File
 import java.io.FileWriter
 
 /**
  * 파일 로깅 세션에서 파일/Writer를 관리합니다.
  *
  * Manages file and writer lifecycle for file logging.
  * <br><br>
  * 파일 로그 세션의 파일 및 writer를 관리합니다.
  */
 internal class LogxFileSession {
     /**
      * 현재 사용 중인 로그 파일입니다.
      *
      * Currently active log file.
      * <br><br>
      * 현재 세션에서 사용 중인 로그 파일입니다.
      */
     private var logFile: File? = null
 
     /**
      * 로그 파일의 식별 시그니처입니다.
      *
      * Signature to detect when a new file should be created.
      * <br><br>
      * 파일 재생성을 판단하기 위한 식별 문자열입니다.
      */
     private var logFileSignature: String? = null
 
     /**
      * 로테이션 기준이 되는 기본 파일명입니다.
      *
      * Base file name seed for rotation.
      * <br><br>
      * 로테이션 시 _count를 붙이기 위한 기준 파일명입니다.
      */
     private var baseFileName: String? = null
 
     /**
      * 로테이션 순번 카운트입니다.
      *
      * Rotation sequence counter.
      * <br><br>
      * 파일 크기 초과 시 증가하는 카운트입니다.
      */
     private var rotationCount: Int = 0
 
     /**
      * 로그 파일에 쓰기 위한 BufferedWriter입니다.
      *
      * BufferedWriter used for appending log lines.
      * <br><br>
      * 로그 라인을 기록하기 위한 writer입니다.
      */
     private var writer: BufferedWriter? = null
 
     /**
      * 현재 설정에 맞는 writer를 반환합니다.
      *
      * Returns a writer for the active log file.
      * <br><br>
      * 현재 설정에 맞는 로그 파일 writer를 반환합니다.
      *
      * @param logDirectory 로그 디렉터리.
      * @param appName 앱 이름.
      * @param storageType 저장 타입.
      */
     fun getWriter(logDirectory: File, appName: String, storageType: LogStorageType): BufferedWriter {
         val signature = "${logDirectory.absolutePath}|${storageType.name}|$appName"
         if (logFile == null || logFileSignature != signature) {
             resetSession()
             logFileSignature = signature
             baseFileName = buildBaseFileName(appName)
             rotationCount = 0
             logFile = createNewFile(logDirectory, baseFileName!!, rotationCount)
         } else if (shouldRotate(logFile)) {
             rotate(logDirectory, appName)
         }
 
         val file = logFile ?: run {
             baseFileName = buildBaseFileName(appName)
             rotationCount = 0
             createNewFile(logDirectory, baseFileName!!, rotationCount).also { created ->
                 logFile = created
                 logFileSignature = signature
             }
         }
 
         return writer ?: BufferedWriter(FileWriter(file, true)).also { writer = it }
     }
 
     /**
      * 열린 writer를 닫습니다.
      *
      * Closes the writer.
      * <br><br>
      * writer를 닫고 writer 상태만 초기화합니다.
      */
     fun close() {
         closeWriter()
     }
 
     private fun resetSession() {
         closeWriter()
         logFile = null
         logFileSignature = null
         baseFileName = null
         rotationCount = 0
     }
 
     private fun closeWriter() {
         safeCatch {
             writer?.close()
         }
         writer = null
     }
 
     private fun rotate(directory: File, appName: String) {
         closeWriter()
         if (baseFileName == null) {
             baseFileName = buildBaseFileName(appName)
             rotationCount = 0
         }
         rotationCount += 1
         logFile = createNewFile(directory, baseFileName!!, rotationCount)
     }
 
     private fun shouldRotate(file: File?): Boolean {
         if (file == null) return false
         return file.length() >= LogxFileConstants.MAX_FILE_SIZE_BYTES
     }
 
     private fun buildBaseFileName(appName: String): String = "${appName}_${LogxTimeUtils.fileTimestamp()}"
 
     /**
      * 새로운 로그 파일을 생성합니다.
      *
      * Creates a new log file under the given directory.
      * <br><br>
      * 지정된 디렉터리에 새 로그 파일을 생성합니다.
      *
      * @param directory 로그 디렉터리.
      * @param baseFileName 기본 파일명(타임스탬프 포함).
      * @param count 로테이션 카운트.
      */
     private fun createNewFile(directory: File, baseFileName: String, count: Int): File {
         val suffix = if (count > 0) "_$count" else ""
         val fileName = "$baseFileName$suffix.txt"
         return File(directory, fileName)
     }
 }