package ru.otus.mobile.driver;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import ru.otus.mobile.config.ProjectPaths;
import ru.otus.mobile.config.TestContext;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.time.Instant;

@Singleton
public final class LogcatCollector {
    private final ProjectPaths projectPaths;

    @Inject
    public LogcatCollector(ProjectPaths projectPaths) {
        this.projectPaths = projectPaths;
    }

    public void save(TestContext context) {
        AndroidDriver driver = context.driver();
        if (driver == null) {
            return;
        }
        try {
            LogEntries entries = driver.manage().logs().get("logcat");
            StringBuilder buffer = new StringBuilder();
            buffer.append("=== ").append(context.testName())
                    .append(" / ").append(context.emulator().id())
                    .append(" / ").append(Instant.now())
                    .append(System.lineSeparator());
            for (LogEntry entry : entries) {
                buffer.append(entry.getTimestamp())
                        .append(' ')
                        .append(entry.getLevel())
                        .append(' ')
                        .append(entry.getMessage())
                        .append(System.lineSeparator());
            }
            Files.writeString(
                    projectPaths.logcatFile(),
                    buffer.append(System.lineSeparator()).toString(),
                    StandardOpenOption.CREATE,
                    StandardOpenOption.APPEND
            );
        } catch (Exception e) {
            writeFallback(context.testName(), e);
        }
    }

    private void writeFallback(String testName, Exception error) {
        try {
            Files.writeString(
                    projectPaths.logcatFile(),
                    "Failed to collect logcat for " + testName + ": " + error.getMessage() + System.lineSeparator(),
                    StandardOpenOption.CREATE,
                    StandardOpenOption.APPEND
            );
        } catch (IOException ignored) {
            // no-op
        }
    }
}
