// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed 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 erofs

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"math"
)

// uncompressedInodeWriter exposes a io.Write-style interface for a single
// uncompressed inode. It splits the Write-calls into blocks and writes both
// the blocks and inode metadata. It is required to call Close() to ensure
// everything is properly written down before writing another inode.
type uncompressedInodeWriter struct {
	buf               bytes.Buffer
	writer            *Writer
	inode             inodeCompact
	baseBlock         uint32 // baseBlock == 0 implies this inode didn't allocate a block (yet).
	writtenBytes      int
	legacyInodeNumber uint32
	pathname          string
}

func (i *uncompressedInodeWriter) allocateBlock() error {
	bb, err := i.writer.allocateBlocks(1)
	if err != nil {
		return err
	}
	if i.baseBlock == 0 {
		i.baseBlock = bb
	}
	return nil
}

func (i *uncompressedInodeWriter) flush(n int) error {
	if err := i.allocateBlock(); err != nil {
		return err
	}
	slice := i.buf.Next(n)
	if _, err := i.writer.w.Write(slice); err != nil {
		return err
	}
	// Always pad to BlockSize.
	_, err := i.writer.w.Write(make([]byte, BlockSize-len(slice)))
	return err
}

func (i *uncompressedInodeWriter) Write(b []byte) (int, error) {
	i.writtenBytes += len(b)
	if _, err := i.buf.Write(b); err != nil {
		return 0, err
	}
	for i.buf.Len() >= BlockSize {
		if err := i.flush(BlockSize); err != nil {
			return 0, err
		}
	}
	return len(b), nil
}

func (i *uncompressedInodeWriter) Close() error {
	if i.buf.Len() > BlockSize {
		panic("programming error")
	}
	inodeSize := binary.Size(i.inode)
	if i.buf.Len()+inodeSize > BlockSize {
		// Can't fit last part of data inline, write it in its own block.
		if err := i.flush(i.buf.Len()); err != nil {
			return err
		}
	}
	if i.buf.Len() == 0 {
		i.inode.Format = inodeFlatPlain << 1
	} else {
		// Colocate last part of data with inode.
		i.inode.Format = inodeFlatInline << 1
	}
	if i.writtenBytes > math.MaxUint32 {
		return errors.New("inodes bigger than 2^32 need the extended inode format which is unsupported by this library")
	}
	i.inode.Size = uint32(i.writtenBytes)
	if i.baseBlock != 0 {
		i.inode.Union = i.baseBlock
	}
	i.inode.HardlinkCount = 1
	i.inode.InodeNumCompat = i.legacyInodeNumber
	basePos, err := i.writer.allocateMetadata(inodeSize+i.buf.Len(), 32)
	if err != nil {
		return fmt.Errorf("failed to allocate metadata: %w", err)
	}
	i.writer.pathInodeMeta[i.pathname] = &uncompressedInodeMeta{
		nid:          uint64(basePos) / 32,
		ftype:        unixModeToFT(i.inode.Mode),
		blockStart:   int64(i.baseBlock),
		blockLength:  (int64(i.writtenBytes) / BlockSize) * BlockSize,
		inlineStart:  basePos + 32,
		inlineLength: int64(i.buf.Len()),
		writer:       i.writer,
	}
	if err := binary.Write(i.writer.w, binary.LittleEndian, &i.inode); err != nil {
		return err
	}
	if i.inode.Format&(inodeFlatInline<<1) != 0 {
		// Data colocated in inode, if any.
		_, err := i.writer.w.Write(i.buf.Bytes())
		return err
	}
	return nil
}
