// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package multipart implements an http.File that acts as one logical file
// backed by several physical files (the 'parts').
package multipart

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"time"
)

var internalErr = fmt.Errorf("internal error")

// NewFile creates the multipart file out of the provided parts.
// The sizes of the parts are captured at the outset and not updated
// for the lifetime of the multipart file (any subsequent modifications
// in the parts will cause Read and Seek to work incorrectly).
func NewFile(name string, parts []*os.File) (http.File, error) {
	fileParts := make([]filePart, len(parts))
	for i, p := range parts {
		stat, err := p.Stat()
		if err != nil {
			return nil, err
		}
		size := stat.Size()
		// TODO(caprita): we can relax this restriction later.
		if size == 0 {
			return nil, fmt.Errorf("Part is empty")
		}
		fileParts[i] = filePart{file: p, size: size}
	}
	return &multipartFile{name: name, parts: fileParts}, nil
}

type filePart struct {
	file *os.File
	size int64
}

type multipartFile struct {
	name       string
	parts      []filePart
	activePart int
	partOffset int64
}

func (m *multipartFile) currPos() (res int64) {
	for i := 0; i < m.activePart; i++ {
		res += m.parts[i].size
	}
	res += m.partOffset
	return
}

func (m *multipartFile) totalSize() (res int64) {
	for _, p := range m.parts {
		res += p.size
	}
	return
}

// Readdir is not implemented.
func (*multipartFile) Readdir(int) ([]os.FileInfo, error) {
	return nil, fmt.Errorf("Not implemented")
}

type fileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

// Name returns the name of the multipart file.
func (f *fileInfo) Name() string {
	return f.name
}

// Size returns the size of the multipart file (the sum of all parts).
func (f *fileInfo) Size() int64 {
	return f.size
}

// Mode is currently hardcoded to 0700.
func (f *fileInfo) Mode() os.FileMode {
	return f.mode
}

// ModTime is set to the current time.
func (f *fileInfo) ModTime() time.Time {
	return f.modTime
}

// IsDir always returns false.
func (f *fileInfo) IsDir() bool {
	return false
}

// Sys always returns nil.
func (f *fileInfo) Sys() interface{} {
	return nil
}

// Stat describes the multipart file.
func (m *multipartFile) Stat() (os.FileInfo, error) {
	return &fileInfo{
		name:    m.name,
		size:    m.totalSize(),
		mode:    0700,
		modTime: time.Now(),
	}, nil
}

// Close closes all the parts.
func (m *multipartFile) Close() error {
	var lastErr error
	for _, p := range m.parts {
		if err := p.file.Close(); err != nil {
			lastErr = err
		}
	}
	return lastErr
}

// Read reads from the parts in sequence.
func (m *multipartFile) Read(buf []byte) (int, error) {
	if m.activePart >= len(m.parts) {
		return 0, io.EOF
	}
	p := m.parts[m.activePart]
	n, err := p.file.Read(buf)
	m.partOffset += int64(n)
	if m.partOffset > p.size {
		// Likely, the file has changed.
		return 0, internalErr
	}
	if m.partOffset == p.size {
		m.activePart++
		if m.activePart < len(m.parts) {
			if _, err := m.parts[m.activePart].file.Seek(0, 0); err != nil {
				return 0, err
			}
			m.partOffset = 0
		}
	}
	return n, err
}

// Seek seeks into the part corresponding to the global offset.
func (m *multipartFile) Seek(offset int64, whence int) (int64, error) {
	var target int64
	switch whence {
	case 0:
		target = offset
	case 1:
		target = m.currPos() + offset
	case 2:
		target = m.totalSize() - offset
	default:
		return 0, fmt.Errorf("invalid whence: %d", whence)
	}
	if target < 0 || target > m.totalSize() {
		return 0, fmt.Errorf("invalid offset")
	}
	var c int64
	for i, p := range m.parts {
		if pSize := p.size; c+pSize <= target {
			c += pSize
			continue
		}
		m.activePart = i
		if _, err := p.file.Seek(target-c, 0); err != nil {
			return 0, err
		}
		m.partOffset = target - c
		return target, nil
	}
	// target <= m.totalSize() should ensure this is never reached.
	return 0, internalErr // Should not be reached.
}
