// 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 storage

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"strings"

	"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/command"
	"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/diff"
)

// DiffOption is an option for Diff.
type DiffOption func(*diffOptions)

// DiffWithSuppressCommands returns a new DiffOption that suppresses printing of commands.
func DiffWithSuppressCommands() DiffOption {
	return func(diffOptions *diffOptions) {
		diffOptions.suppressCommands = true
	}
}

// DiffWithSuppressCommands returns a new DiffOption that suppresses printing of timestamps.
func DiffWithSuppressTimestamps() DiffOption {
	return func(diffOptions *diffOptions) {
		diffOptions.suppressTimestamps = true
	}
}

// DiffWithExternalPaths returns a new DiffOption that prints diffs with external paths
// instead of paths.
func DiffWithExternalPaths() DiffOption {
	return func(diffOptions *diffOptions) {
		diffOptions.externalPaths = true
	}
}

// DiffWithExternalPathPrefixes returns a new DiffOption that sets the external path prefixes for the buckets.
//
// If a file is in one bucket but not the other, it will be assumed that the file begins
// with the given prefix, and this prefix should be substituted for the other prefix.
//
// For example, if diffing the directories "test/a" and "test/b", use "test/a/" and "test/b/",
// and a file that is in one with path "test/a/foo.txt" will be shown as not
// existing as "test/b/foo.txt" in two.
//
// Note that the prefixes are directly concatenated, so "/" should be included generally.
//
// This option has no effect if DiffWithExternalPaths is not set.
// This option is not required if the prefixes are equal.
func DiffWithExternalPathPrefixes(
	oneExternalPathPrefix string,
	twoExternalPathPrefix string,
) DiffOption {
	return func(diffOptions *diffOptions) {
		if oneExternalPathPrefix != twoExternalPathPrefix {
			// we don't know if external paths are file paths or not
			// so we just operate on pure string-prefix paths
			// this comes up with for example s3://
			diffOptions.oneExternalPathPrefix = oneExternalPathPrefix
			diffOptions.twoExternalPathPrefix = twoExternalPathPrefix
		}
	}
}

// DiffWithTransform returns a DiffOption that adds a transform function. The transform function will be run on each
// file being compared before it is diffed. transform takes the arguments:
//
//	side: one or two whether it is the first or second item in the diff
//	filename: the filename including path
//	content: the file content.
//
// transform returns a string that is the transformed content of filename.
//
// TODO: this needs to be refactored or removed, especially the implicit side enum.
// Perhaps provide a transform function for a given bucket and apply it there.
func DiffWithTransform(
	transform func(side string, filename string, content []byte) []byte,
) DiffOption {
	return func(diffOptions *diffOptions) {
		diffOptions.transforms = append(diffOptions.transforms, transform)
	}
}

// DiffBytes does a diff of the ReadBuckets.
func DiffBytes(
	ctx context.Context,
	runner command.Runner,
	one ReadBucket,
	two ReadBucket,
	options ...DiffOption,
) ([]byte, error) {
	buffer := bytes.NewBuffer(nil)
	if err := Diff(ctx, runner, buffer, one, two, options...); err != nil {
		return nil, err
	}
	return buffer.Bytes(), nil
}

// Diff writes a diff of the ReadBuckets to the Writer.
func Diff(
	ctx context.Context,
	runner command.Runner,
	writer io.Writer,
	one ReadBucket,
	two ReadBucket,
	options ...DiffOption,
) error {
	diffOptions := newDiffOptions()
	for _, option := range options {
		option(diffOptions)
	}
	externalPaths := diffOptions.externalPaths
	oneExternalPathPrefix := diffOptions.oneExternalPathPrefix
	twoExternalPathPrefix := diffOptions.twoExternalPathPrefix

	oneObjectInfos, err := allObjectInfos(ctx, one, "")
	if err != nil {
		return err
	}
	twoObjectInfos, err := allObjectInfos(ctx, two, "")
	if err != nil {
		return err
	}
	sortObjectInfos(oneObjectInfos)
	sortObjectInfos(twoObjectInfos)
	onePathToObjectInfo := pathToObjectInfo(oneObjectInfos)
	twoPathToObjectInfo := pathToObjectInfo(twoObjectInfos)

	for _, oneObjectInfo := range oneObjectInfos {
		path := oneObjectInfo.Path()
		oneDiffPath, err := getDiffPathForObjectInfo(
			oneObjectInfo,
			externalPaths,
			oneExternalPathPrefix,
		)
		if err != nil {
			return err
		}
		oneData, err := ReadPath(ctx, one, path)
		if err != nil {
			return err
		}
		var twoData []byte
		var twoDiffPath string
		if twoObjectInfo, ok := twoPathToObjectInfo[path]; ok {
			twoData, err = ReadPath(ctx, two, path)
			if err != nil {
				return err
			}
			twoDiffPath, err = getDiffPathForObjectInfo(
				twoObjectInfo,
				externalPaths,
				twoExternalPathPrefix,
			)
			if err != nil {
				return err
			}
		} else {
			twoDiffPath, err = getDiffPathForNotFound(
				oneObjectInfo,
				externalPaths,
				oneExternalPathPrefix,
				twoExternalPathPrefix,
			)
			if err != nil {
				return err
			}
		}
		for _, transform := range diffOptions.transforms {
			oneData = transform("one", oneDiffPath, oneData)
			twoData = transform("two", twoDiffPath, twoData)
		}
		diffData, err := diff.Diff(
			ctx,
			runner,
			oneData,
			twoData,
			oneDiffPath,
			twoDiffPath,
			diffOptions.toDiffPackageOptions()...,
		)
		if err != nil {
			return err
		}
		if len(diffData) > 0 {
			if _, err := writer.Write(diffData); err != nil {
				return err
			}
		}
	}
	for _, twoObjectInfo := range twoObjectInfos {
		path := twoObjectInfo.Path()
		if _, ok := onePathToObjectInfo[path]; !ok {
			twoData, err := ReadPath(ctx, two, path)
			if err != nil {
				return err
			}
			oneDiffPath, err := getDiffPathForNotFound(
				twoObjectInfo,
				externalPaths,
				twoExternalPathPrefix,
				oneExternalPathPrefix,
			)
			if err != nil {
				return err
			}
			twoDiffPath, err := getDiffPathForObjectInfo(
				twoObjectInfo,
				externalPaths,
				twoExternalPathPrefix,
			)
			if err != nil {
				return err
			}
			diffData, err := diff.Diff(
				ctx,
				runner,
				nil,
				twoData,
				oneDiffPath,
				twoDiffPath,
				diffOptions.toDiffPackageOptions()...,
			)
			if err != nil {
				return err
			}
			if len(diffData) > 0 {
				if _, err := writer.Write(diffData); err != nil {
					return err
				}
			}
		}
	}
	return nil
}

func getDiffPathForObjectInfo(
	objectInfo ObjectInfo,
	externalPaths bool,
	externalPathPrefix string,
) (string, error) {
	if !externalPaths {
		return objectInfo.Path(), nil
	}
	externalPath := objectInfo.ExternalPath()
	if externalPathPrefix == "" {
		return externalPath, nil
	}
	if !strings.HasPrefix(externalPath, externalPathPrefix) {
		return "", fmt.Errorf("diff: expected %s to have prefix %s", externalPath, externalPathPrefix)
	}
	return externalPath, nil
}

func getDiffPathForNotFound(
	foundObjectInfo ObjectInfo,
	externalPaths bool,
	foundExternalPathPrefix string,
	notFoundExternalPathPrefix string,
) (string, error) {
	if !externalPaths {
		return foundObjectInfo.Path(), nil
	}
	externalPath := foundObjectInfo.ExternalPath()
	switch {
	case foundExternalPathPrefix == "" && notFoundExternalPathPrefix == "":
		// no prefix, just return external path
		return externalPath, nil
	case foundExternalPathPrefix == "" && notFoundExternalPathPrefix != "":
		// the not-found side has a prefix, append the external path to this prefix, and we're done
		return notFoundExternalPathPrefix + externalPath, nil
	default:
		// foundExternalPathPrefix != "" && notFoundExternalPathPrefix == ""
		// foundExternalPathPrefix != "" && notFoundExternalPathPrefix != ""
		if !strings.HasPrefix(externalPath, foundExternalPathPrefix) {
			return "", fmt.Errorf("diff: expected %s to have prefix %s", externalPath, foundExternalPathPrefix)
		}
		return notFoundExternalPathPrefix + strings.TrimPrefix(externalPath, foundExternalPathPrefix), nil
	}
}

type diffOptions struct {
	suppressCommands      bool
	suppressTimestamps    bool
	externalPaths         bool
	oneExternalPathPrefix string
	twoExternalPathPrefix string
	transforms            []func(side string, filename string, content []byte) []byte
}

func newDiffOptions() *diffOptions {
	return &diffOptions{}
}

func (d *diffOptions) toDiffPackageOptions() []diff.DiffOption {
	var diffPackageOptions []diff.DiffOption
	if d.suppressCommands {
		diffPackageOptions = append(diffPackageOptions, diff.DiffWithSuppressCommands())
	}
	if d.suppressTimestamps {
		diffPackageOptions = append(diffPackageOptions, diff.DiffWithSuppressTimestamps())
	}
	return diffPackageOptions
}
