// Copyright 2011 The Go 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 zip

import (
	"bufio"
	"compress/flate"
	"encoding/binary"
	"hash"
	"hash/crc32"
	"io"
	"os"
)

// TODO(adg): support zip file comments
// TODO(adg): support specifying deflate level

// Writer implements a zip file writer.
type Writer struct {
	*countWriter
	dir    []*header
	last   *fileWriter
	closed bool
}

type header struct {
	*FileHeader
	offset uint32
}

// NewWriter returns a new Writer writing a zip file to w.
func NewWriter(w io.Writer) *Writer {
	return &Writer{countWriter: &countWriter{w: bufio.NewWriter(w)}}
}

// Close finishes writing the zip file by writing the central directory.
// It does not (and can not) close the underlying writer.
func (w *Writer) Close() (err os.Error) {
	if w.last != nil && !w.last.closed {
		if err = w.last.close(); err != nil {
			return
		}
		w.last = nil
	}
	if w.closed {
		return os.NewError("zip: writer closed twice")
	}
	w.closed = true

	defer recoverError(&err)

	// write central directory
	start := w.count
	for _, h := range w.dir {
		write(w, uint32(directoryHeaderSignature))
		write(w, h.CreatorVersion)
		write(w, h.ReaderVersion)
		write(w, h.Flags)
		write(w, h.Method)
		write(w, h.ModifiedTime)
		write(w, h.ModifiedDate)
		write(w, h.CRC32)
		write(w, h.CompressedSize)
		write(w, h.UncompressedSize)
		write(w, uint16(len(h.Name)))
		write(w, uint16(len(h.Extra)))
		write(w, uint16(len(h.Comment)))
		write(w, uint16(0)) // disk number start
		write(w, uint16(0)) // internal file attributes
		write(w, uint32(0)) // external file attributes
		write(w, h.offset)
		writeBytes(w, []byte(h.Name))
		writeBytes(w, h.Extra)
		writeBytes(w, []byte(h.Comment))
	}
	end := w.count

	// write end record
	write(w, uint32(directoryEndSignature))
	write(w, uint16(0))          // disk number
	write(w, uint16(0))          // disk number where directory starts
	write(w, uint16(len(w.dir))) // number of entries this disk
	write(w, uint16(len(w.dir))) // number of entries total
	write(w, uint32(end-start))  // size of directory
	write(w, uint32(start))      // start of directory
	write(w, uint16(0))          // size of comment

	return w.w.(*bufio.Writer).Flush()
}

// Create adds a file to the zip file using the provided name.
// It returns a Writer to which the file contents should be written.
// The file's contents must be written to the io.Writer before the next
// call to Create, CreateHeader, or Close.
func (w *Writer) Create(name string) (io.Writer, os.Error) {
	header := &FileHeader{
		Name:   name,
		Method: Deflate,
	}
	return w.CreateHeader(header)
}

// CreateHeader adds a file to the zip file using the provided FileHeader
// for the file metadata. 
// It returns a Writer to which the file contents should be written.
// The file's contents must be written to the io.Writer before the next
// call to Create, CreateHeader, or Close.
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, os.Error) {
	if w.last != nil && !w.last.closed {
		if err := w.last.close(); err != nil {
			return nil, err
		}
	}

	fh.Flags |= 0x8 // we will write a data descriptor
	fh.CreatorVersion = 0x14
	fh.ReaderVersion = 0x14

	fw := &fileWriter{
		zipw:      w,
		compCount: &countWriter{w: w},
		crc32:     crc32.NewIEEE(),
	}
	switch fh.Method {
	case Store:
		fw.comp = nopCloser{fw.compCount}
	case Deflate:
		fw.comp = flate.NewWriter(fw.compCount, 5)
	default:
		return nil, UnsupportedMethod
	}
	fw.rawCount = &countWriter{w: fw.comp}

	h := &header{
		FileHeader: fh,
		offset:     uint32(w.count),
	}
	w.dir = append(w.dir, h)
	fw.header = h

	if err := writeHeader(w, fh); err != nil {
		return nil, err
	}

	w.last = fw
	return fw, nil
}

func writeHeader(w io.Writer, h *FileHeader) (err os.Error) {
	defer recoverError(&err)
	write(w, uint32(fileHeaderSignature))
	write(w, h.ReaderVersion)
	write(w, h.Flags)
	write(w, h.Method)
	write(w, h.ModifiedTime)
	write(w, h.ModifiedDate)
	write(w, h.CRC32)
	write(w, h.CompressedSize)
	write(w, h.UncompressedSize)
	write(w, uint16(len(h.Name)))
	write(w, uint16(len(h.Extra)))
	writeBytes(w, []byte(h.Name))
	writeBytes(w, h.Extra)
	return nil
}

type fileWriter struct {
	*header
	zipw      io.Writer
	rawCount  *countWriter
	comp      io.WriteCloser
	compCount *countWriter
	crc32     hash.Hash32
	closed    bool
}

func (w *fileWriter) Write(p []byte) (int, os.Error) {
	if w.closed {
		return 0, os.NewError("zip: write to closed file")
	}
	w.crc32.Write(p)
	return w.rawCount.Write(p)
}

func (w *fileWriter) close() (err os.Error) {
	if w.closed {
		return os.NewError("zip: file closed twice")
	}
	w.closed = true
	if err = w.comp.Close(); err != nil {
		return
	}

	// update FileHeader
	fh := w.header.FileHeader
	fh.CRC32 = w.crc32.Sum32()
	fh.CompressedSize = uint32(w.compCount.count)
	fh.UncompressedSize = uint32(w.rawCount.count)

	// write data descriptor
	defer recoverError(&err)
	write(w.zipw, fh.CRC32)
	write(w.zipw, fh.CompressedSize)
	write(w.zipw, fh.UncompressedSize)

	return nil
}

type countWriter struct {
	w     io.Writer
	count int64
}

func (w *countWriter) Write(p []byte) (int, os.Error) {
	n, err := w.w.Write(p)
	w.count += int64(n)
	return n, err
}

type nopCloser struct {
	io.Writer
}

func (w nopCloser) Close() os.Error {
	return nil
}

func write(w io.Writer, data interface{}) {
	if err := binary.Write(w, binary.LittleEndian, data); err != nil {
		panic(err)
	}
}

func writeBytes(w io.Writer, b []byte) {
	n, err := w.Write(b)
	if err != nil {
		panic(err)
	}
	if n != len(b) {
		panic(io.ErrShortWrite)
	}
}
