package main

import (
	"os"
)

// 作业2：日志系统（难度：⭐⭐）
// 题目： 实现支持多种输出方式的日志系统。

// 1. 定义Logger接口
type Logger interface {
	Log(message string)
}

// 2. 实现ConsoleLogger（控制台输出）
type ConsoleLogger struct{}

func (c *ConsoleLogger) Log(message string) {
	println("控制台日志:", message)
}

// 3. 实现FileLogger（文件输出）
type FileLogger struct {
	filename string
	logFile  *os.File
	size     int64
}

func (f *FileLogger) Log(message string) {
	// 模拟文件写入
	println("文件日志:", message, "写入到文件:", f.filename)

	// 如果没有指定文件名，使用默认文件名
	if f.filename == "" {
		f.filename = "app.log"
	}

	// O_APPEND
	if f.logFile == nil {
		logFile, err := os.OpenFile(f.filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
		if err != nil {
			panic(err)
		}
		// 获取当前日志文件的大小
		fileInfo, err := f.logFile.Stat()
		if err != nil {
			panic(err)
		}
		// 初始文件大小
		f.size = fileInfo.Size()
		f.logFile = logFile
	}

	// 如果文件大小超过10M，则创建新的文件
	if f.size >= 10*1024*1024 {
		f.logFile.Close()
		f.filename = f.filename + ".1"
		logFile, err := os.OpenFile(f.filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
		if err != nil {
			panic(err)
		}
		f.logFile = logFile
		f.size = 0
	}

	n, err := f.logFile.WriteString(message + "\n")
	if err != nil {
		panic(err)
	}
	f.size += int64(n)
}

// 4. 实现MultiLogger（同时输出到多个地方）
type MultiLogger struct {
	loggers []Logger
}

// 5. 实现MultiLogger
func (m *MultiLogger) Log(message string) {
	for _, logger := range m.loggers {
		logger.Log(message)
	}
}

func (m *MultiLogger) Close() {
	for _, logger := range m.loggers {
		if fileLogger, ok := logger.(*FileLogger); ok {
			if fileLogger.logFile != nil {
				fileLogger.logFile.Close()
			}
		}
	}
}

func main() {
	logger := &MultiLogger{
		loggers: []Logger{
			&ConsoleLogger{},
			&FileLogger{filename: "app.log"},
		},
	}
	defer logger.Close()

	logger.Log("应用启动")
	logger.Log("用户登录")
}
