Code cleanup

Change-Id: I084eb212ae4a1fdbc563e686ea6c9de55fc75914
diff --git a/DESCRIPTION b/DESCRIPTION
index 1e47e7a..17fc787 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -64,6 +64,7 @@
     raster,
     tidyverse
 Collate: 
+    'logging.R'
     'KorAPConnection.R'
     'KorAPCorpusStats.R'
     'RKorAPClient-package.R'
@@ -77,5 +78,4 @@
     'misc.R'
     'reexports.R'
     'textMetadata.R'
-    'logging.R'
 Roxygen: list(markdown = TRUE)
diff --git a/man/calculate_eta.Rd b/man/calculate_eta.Rd
new file mode 100644
index 0000000..5d524e4
--- /dev/null
+++ b/man/calculate_eta.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/logging.R
+\name{calculate_eta}
+\alias{calculate_eta}
+\title{Calculate and format ETA for batch operations}
+\usage{
+calculate_eta(current_item, total_items, start_time)
+}
+\arguments{
+\item{current_item}{current item number (1-based)}
+
+\item{total_items}{total number of items to process}
+
+\item{start_time}{POSIXct start time of the operation}
+}
+\value{
+character string with formatted ETA and completion time or empty string if not calculable
+}
+\description{
+Helper function to calculate estimated time of arrival based on elapsed time
+and progress through a batch operation.
+}
+\keyword{internal}
diff --git a/man/collocationAnalysis-KorAPConnection-method.Rd b/man/collocationAnalysis-KorAPConnection-method.Rd
index 50f4a27..6b13db7 100644
--- a/man/collocationAnalysis-KorAPConnection-method.Rd
+++ b/man/collocationAnalysis-KorAPConnection-method.Rd
@@ -100,10 +100,12 @@
 \examples{
 \dontrun{
 
- # Find top collocates of "Packung" inside and outside the sports domain.
- KorAPConnection(verbose = TRUE) |>
-  collocationAnalysis("Packung", vc=c("textClass=sport", "textClass!=sport"),
-                      leftContextSize=1, rightContextSize=1, topCollocatesLimit=20) |>
+# Find top collocates of "Packung" inside and outside the sports domain.
+KorAPConnection(verbose = TRUE) |>
+  collocationAnalysis("Packung",
+    vc = c("textClass=sport", "textClass!=sport"),
+    leftContextSize = 1, rightContextSize = 1, topCollocatesLimit = 20
+  ) |>
   dplyr::filter(logDice >= 5)
 }
 
@@ -113,7 +115,8 @@
 # Note that, currently, the use of focus function disallows exactFrequencies.
 KorAPConnection(verbose = TRUE) |>
   collocationAnalysis("focus(in [tt/p=NN] {[tt/l=setzen]})",
-    leftContextSize=1, rightContextSize=0, exactFrequencies=FALSE, topCollocatesLimit=20)
+    leftContextSize = 1, rightContextSize = 0, exactFrequencies = FALSE, topCollocatesLimit = 20
+  )
 }
 
 }
diff --git a/man/corpusStats-KorAPConnection-method.Rd b/man/corpusStats-KorAPConnection-method.Rd
index 055585b..961d64b 100644
--- a/man/corpusStats-KorAPConnection-method.Rd
+++ b/man/corpusStats-KorAPConnection-method.Rd
@@ -23,7 +23,6 @@
 Fetch information about a (virtual) corpus
 }
 \examples{
-
 \dontrun{
 
 kco <- KorAPConnection()
diff --git a/man/format_duration.Rd b/man/format_duration.Rd
new file mode 100644
index 0000000..ce811c0
--- /dev/null
+++ b/man/format_duration.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/logging.R
+\name{format_duration}
+\alias{format_duration}
+\title{Format duration in seconds to human-readable format}
+\usage{
+format_duration(seconds)
+}
+\arguments{
+\item{seconds}{numeric duration in seconds}
+}
+\value{
+character string with formatted duration
+}
+\description{
+Converts a duration in seconds to a formatted string with days, hours, minutes, and seconds.
+Used for ETA calculations and progress reporting.
+}
+\examples{
+\dontrun{
+format_duration(3661) # "01h 01m 01s"
+format_duration(86461) # "1d 00h 01m 01s"
+}
+}
+\keyword{internal}
diff --git a/man/log_info.Rd b/man/log_info.Rd
new file mode 100644
index 0000000..6e5d2c7
--- /dev/null
+++ b/man/log_info.Rd
@@ -0,0 +1,19 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/logging.R
+\name{log_info}
+\alias{log_info}
+\title{Logging utilities for RKorAPClient}
+\usage{
+log_info(v, ...)
+}
+\arguments{
+\item{v}{logical flag indicating whether to output the message}
+
+\item{...}{message components to concatenate and display}
+}
+\description{
+This module provides centralized logging functions used throughout the package
+for progress reporting and ETA calculations.
+Log informational messages with optional coloring
+}
+\keyword{internal}
diff --git a/tests/testthat/test-KorAPConnection.R b/tests/testthat/test-KorAPConnection.R
index 8267773..114c8c9 100644
--- a/tests/testthat/test-KorAPConnection.R
+++ b/tests/testthat/test-KorAPConnection.R
@@ -1,13 +1,13 @@
 test_that("KorAPConnection fails gracefully on unresolvable host", {
-  expect_message(KorAPConnection(accessToken = NULL, apiUrl="http://xxx.asdhsahdsadhvgas.org"), "No internet|Could not resolve")
+  expect_message(KorAPConnection(accessToken = NULL, apiUrl = "http://xxx.asdhsahdsadhvgas.org"), "No internet|Could not resolve")
 })
 
 test_that("KorAPConnection fails gracefully on timeout", {
-  expect_message(KorAPConnection(apiUrl="http://httpbin.org/delay/3", accessToken = NULL, timeout = 0.2), "No internet|Timeout|json|progress|Unavailable")
+  expect_message(KorAPConnection(apiUrl = "http://httpbin.org/delay/3", accessToken = NULL, timeout = 0.2), "No internet|Timeout|json|progress|Unavailable")
 })
 
 test_that("KorAPConnection fails gracefully on Bad Gateway errors", {
-  expect_message(KorAPConnection(apiUrl="http://httpbin.org/status/502", accessToken = NULL, timeout = 0.5), "No internet|Timeout|progress|json|502")
+  expect_message(KorAPConnection(apiUrl = "http://httpbin.org/status/502", accessToken = NULL, timeout = 0.5), "No internet|Timeout|progress|json|502")
 })
 
 test_that("KorAPConnection is printable", {
@@ -21,8 +21,10 @@
 })
 
 test_that("Opening KorAPConnection with invalid apiToken fails gracefully", {
-  expect_message(KorAPConnection(accessToken="test token", timeout = 3),
-               "401|Timeout|progress")
+  expect_message(
+    KorAPConnection(accessToken = "test token", timeout = 3),
+    "401|Timeout|progress"
+  )
 })
 
 test_that("Persisting null apiToken fails", {
@@ -30,13 +32,14 @@
   skip_if_not(is.null(kco@accessToken))
   skip_if(is.null(kco@welcome))
   expect_error(persistAccessToken(kco),
-               ".*not supplied any access token.*",
-               perl = TRUE)
+    ".*not supplied any access token.*",
+    perl = TRUE
+  )
 })
 
 test_that("Opening KorAPConnection with KorAPUrl works", {
-  kco <- KorAPConnection(accessToken = NULL, KorAPUrl="https://korap.ids-mannheim.de", timeout = 1)
+  kco <- KorAPConnection(accessToken = NULL, KorAPUrl = "https://korap.ids-mannheim.de", timeout = 1)
   expect_equal(kco@apiUrl, paste0("https://korap.ids-mannheim.de/api/", kco@apiVersion, "/"))
-  kco <- KorAPConnection(accessToken = NULL, KorAPUrl="https://korap.ids-mannheim.de/", timeout = 1)
+  kco <- KorAPConnection(accessToken = NULL, KorAPUrl = "https://korap.ids-mannheim.de/", timeout = 1)
   expect_equal(kco@apiUrl, paste0("https://korap.ids-mannheim.de/api/", kco@apiVersion, "/"))
 })