/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package filter_impl

import (
	"context"
	"os"
	"reflect"
	"strings"
	"time"
)

import (
	"github.com/apache/dubbo-go/common/constant"
	"github.com/apache/dubbo-go/common/extension"
	"github.com/apache/dubbo-go/common/logger"
	"github.com/apache/dubbo-go/filter"
	"github.com/apache/dubbo-go/protocol"
)

const (
	//used in URL.

	// nolint
	FileDateFormat = "2006-01-02"
	// nolint
	MessageDateLayout = "2006-01-02 15:04:05"
	// nolint
	LogMaxBuffer = 5000
	// nolint
	LogFileMode = 0600

	// those fields are the data collected by this filter

	// nolint
	Types = "types"
	// nolint
	Arguments = "arguments"
)

func init() {
	extension.SetFilter(constant.ACCESS_LOG_KEY, GetAccessLogFilter)
}

/*
 * AccessLogFilter
 * Although the access log filter is a default filter,
 * you should config "accesslog" in service's config to tell the filter where store the access log.
 * for example:
 * "UserProvider":
 *   registry: "hangzhouzk"
 *   protocol : "dubbo"
 *   interface : "com.ikurento.user.UserProvider"
 *   ... # other configuration
 *   accesslog: "/your/path/to/store/the/log/", # it should be the path of file.
 *
 * the value of "accesslog" can be "true" or "default" too.
 * If the value is one of them, the access log will be record in log file which defined in log.yml
 * AccessLogFilter is designed to be singleton
 */
type AccessLogFilter struct {
	logChan chan AccessLogData
}

// Invoke will check whether user wants to use this filter.
// If we find the value of key constant.ACCESS_LOG_KEY, we will log the invocation info
func (ef *AccessLogFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
	accessLog := invoker.GetUrl().GetParam(constant.ACCESS_LOG_KEY, "")

	// the user do not
	if len(accessLog) > 0 {
		accessLogData := AccessLogData{data: ef.buildAccessLogData(invoker, invocation), accessLog: accessLog}
		ef.logIntoChannel(accessLogData)
	}
	return invoker.Invoke(ctx, invocation)
}

// logIntoChannel won't block the invocation
func (ef *AccessLogFilter) logIntoChannel(accessLogData AccessLogData) {
	select {
	case ef.logChan <- accessLogData:
		return
	default:
		logger.Warn("The channel is full and the access logIntoChannel data will be dropped")
		return
	}
}

// buildAccessLogData builds the access log data
func (ef *AccessLogFilter) buildAccessLogData(_ protocol.Invoker, invocation protocol.Invocation) map[string]string {
	dataMap := make(map[string]string, 16)
	attachments := invocation.Attachments()
	itf := attachments[constant.INTERFACE_KEY]
	if itf == nil || len(itf.(string)) == 0 {
		itf = attachments[constant.PATH_KEY]
	}
	if itf != nil {
		dataMap[constant.INTERFACE_KEY] = itf.(string)
	}
	if v, ok := attachments[constant.METHOD_KEY]; ok && v != nil {
		dataMap[constant.METHOD_KEY] = v.(string)
	}
	if v, ok := attachments[constant.VERSION_KEY]; ok && v != nil {
		dataMap[constant.VERSION_KEY] = v.(string)
	}
	if v, ok := attachments[constant.GROUP_KEY]; ok && v != nil {
		dataMap[constant.GROUP_KEY] = v.(string)
	}
	if v, ok := attachments[constant.TIMESTAMP_KEY]; ok && v != nil {
		dataMap[constant.TIMESTAMP_KEY] = v.(string)
	}
	if v, ok := attachments[constant.LOCAL_ADDR]; ok && v != nil {
		dataMap[constant.LOCAL_ADDR] = v.(string)
	}
	if v, ok := attachments[constant.REMOTE_ADDR]; ok && v != nil {
		dataMap[constant.REMOTE_ADDR] = v.(string)
	}

	if len(invocation.Arguments()) > 0 {
		builder := strings.Builder{}
		// todo(after the paramTypes were set to the invocation. we should change this implementation)
		typeBuilder := strings.Builder{}

		builder.WriteString(reflect.ValueOf(invocation.Arguments()[0]).String())
		typeBuilder.WriteString(reflect.TypeOf(invocation.Arguments()[0]).Name())
		for idx := 1; idx < len(invocation.Arguments()); idx++ {
			arg := invocation.Arguments()[idx]
			builder.WriteString(",")
			builder.WriteString(reflect.ValueOf(arg).String())

			typeBuilder.WriteString(",")
			typeBuilder.WriteString(reflect.TypeOf(arg).Name())
		}
		dataMap[Arguments] = builder.String()
		dataMap[Types] = typeBuilder.String()
	}

	return dataMap
}

// OnResponse do nothing
func (ef *AccessLogFilter) OnResponse(_ context.Context, result protocol.Result, _ protocol.Invoker, _ protocol.Invocation) protocol.Result {
	return result
}

// writeLogToFile actually write the logs into file
func (ef *AccessLogFilter) writeLogToFile(data AccessLogData) {
	accessLog := data.accessLog
	if isDefault(accessLog) {
		logger.Info(data.toLogMessage())
		return
	}

	logFile, err := ef.openLogFile(accessLog)
	if err != nil {
		logger.Warnf("Can not open the access log file: %s, %v", accessLog, err)
		return
	}
	logger.Debugf("Append log to %s", accessLog)
	message := data.toLogMessage()
	message = message + "\n"
	_, err = logFile.WriteString(message)
	if err != nil {
		logger.Warnf("Can not write the log into access log file: %s, %v", accessLog, err)
	}
}

// openLogFile will open the log file with append mode.
// If the file is not found, it will create the file.
// Actually, the accessLog is the filename
// You may find out that, once we want to write access log into log file,
// we open the file again and again.
// It needs to be optimized.
func (ef *AccessLogFilter) openLogFile(accessLog string) (*os.File, error) {
	logFile, err := os.OpenFile(accessLog, os.O_CREATE|os.O_APPEND|os.O_RDWR, LogFileMode)
	if err != nil {
		logger.Warnf("Can not open the access log file: %s, %v", accessLog, err)
		return nil, err
	}
	now := time.Now().Format(FileDateFormat)
	fileInfo, err := logFile.Stat()
	if err != nil {
		logger.Warnf("Can not get the info of access log file: %s, %v", accessLog, err)
		return nil, err
	}
	last := fileInfo.ModTime().Format(FileDateFormat)

	// this is confused.
	// for example, if the last = '2020-03-04'
	// and today is '2020-03-05'
	// we will create one new file to log access data
	// By this way, we can split the access log based on days.
	if now != last {
		err = os.Rename(fileInfo.Name(), fileInfo.Name()+"."+now)
		if err != nil {
			logger.Warnf("Can not rename access log file: %s, %v", fileInfo.Name(), err)
			return nil, err
		}
		logFile, err = os.OpenFile(accessLog, os.O_CREATE|os.O_APPEND|os.O_RDWR, LogFileMode)
	}
	return logFile, err
}

// isDefault check whether accessLog == true or accessLog == default
func isDefault(accessLog string) bool {
	return strings.EqualFold("true", accessLog) || strings.EqualFold("default", accessLog)
}

// GetAccessLogFilter return the instance of AccessLogFilter
func GetAccessLogFilter() filter.Filter {
	accessLogFilter := &AccessLogFilter{logChan: make(chan AccessLogData, LogMaxBuffer)}
	go func() {
		for accessLogData := range accessLogFilter.logChan {
			accessLogFilter.writeLogToFile(accessLogData)
		}
	}()
	return accessLogFilter
}

// AccessLogData defines the data that will be log into file
type AccessLogData struct {
	accessLog string
	data      map[string]string
}

// toLogMessage convert the AccessLogData to String
func (ef *AccessLogData) toLogMessage() string {
	builder := strings.Builder{}
	builder.WriteString("[")
	builder.WriteString(ef.data[constant.TIMESTAMP_KEY])
	builder.WriteString("] ")
	builder.WriteString(ef.data[constant.REMOTE_ADDR])
	builder.WriteString(" -> ")
	builder.WriteString(ef.data[constant.LOCAL_ADDR])
	builder.WriteString(" - ")
	if len(ef.data[constant.GROUP_KEY]) > 0 {
		builder.WriteString(ef.data[constant.GROUP_KEY])
		builder.WriteString("/")
	}

	builder.WriteString(ef.data[constant.INTERFACE_KEY])

	if len(ef.data[constant.VERSION_KEY]) > 0 {
		builder.WriteString(":")
		builder.WriteString(ef.data[constant.VERSION_KEY])
	}

	builder.WriteString(" ")
	builder.WriteString(ef.data[constant.METHOD_KEY])
	builder.WriteString("(")
	if len(ef.data[Types]) > 0 {
		builder.WriteString(ef.data[Types])
	}
	builder.WriteString(") ")

	if len(ef.data[Arguments]) > 0 {
		builder.WriteString(ef.data[Arguments])
	}
	return builder.String()
}
