/********************************************************************
 * 2014 -
 * open source under Apache License Version 2.0
 ********************************************************************/
/**
 * 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.
 */
#include "Atomic.h"
#include "DateTime.h"
#include "Exception.h"
#include "ExceptionInternal.h"
#include "FileSystemInter.h"
#include "HWCrc32c.h"
#include "LeaseRenewer.h"
#include "Logger.h"
#include "OutputStream.h"
#include "OutputStreamImpl.h"
#include "Packet.h"
#include "PacketHeader.h"
#include "SWCrc32c.h"

#include <cassert>
#include <inttypes.h>

namespace Hdfs {
namespace Internal {

OutputStreamImpl::OutputStreamImpl() :
/*heartBeatStop(true),*/ closed(true), isAppend(false), syncBlock(false), checksumSize(0), chunkSize(
        0), chunksPerPacket(0), closeTimeout(0), heartBeatInterval(0), packetSize(0), position(
            0), replication(0), blockSize(0), bytesWritten(0), cursor(0), lastFlushed(
                0), nextSeqNo(0), packets(0), cryptoCodec(NULL), kcp(NULL) {
    if (HWCrc32c::available()) {
        checksum = shared_ptr < Checksum > (new HWCrc32c());
    } else {
        checksum = shared_ptr < Checksum > (new SWCrc32c());
    }

    checksumSize = sizeof(int32_t);
    lastSend = steady_clock::now();
#ifdef MOCK
    stub = NULL;
#endif
}

OutputStreamImpl::~OutputStreamImpl() {
    if (!closed) {
        try {
            close();
        } catch (...) {
        }
    }
}

void OutputStreamImpl::checkStatus() {
    if (closed) {
        THROW(HdfsIOException, "OutputStreamImpl: stream is not opened.");
    }

    lock_guard < mutex > lock(mut);

    if (lastError != exception_ptr()) {
        rethrow_exception(lastError);
    }
}

void OutputStreamImpl::setError(const exception_ptr & error) {
    try {
        lock_guard < mutex > lock(mut);
        lastError = error;
    } catch (...) {
    }
}

shared_ptr<CryptoCodec> OutputStreamImpl::getCryptoCodec() {
    return cryptoCodec;
}

void OutputStreamImpl::setCryptoCodec(shared_ptr<CryptoCodec> cryptoCodec) {
    this->cryptoCodec = cryptoCodec;
}

shared_ptr<KmsClientProvider> OutputStreamImpl::getKmsClientProvider() {
    return kcp;
}

void OutputStreamImpl::setKmsClientProvider(shared_ptr<KmsClientProvider> kcp) {
    this->kcp = kcp;
}
/**
 * To create or append a file.
 * @param fs hdfs file system.
 * @param path the file path.
 * @param flag creation flag, can be Create, Append or Create|Overwrite.
 * @param permission create a new file with given permission.
 * @param createParent if the parent does not exist, create it.
 * @param replication create a file with given number of replication.
 * @param blockSize  create a file with given block size.
 */
void OutputStreamImpl::open(shared_ptr<FileSystemInter> fs, const char * path, int flag,
                            const Permission & permission, bool createParent, int replication,
                            int64_t blockSize) {
    if (NULL == path || 0 == strlen(path) || replication < 0 || blockSize < 0) {
        THROW(InvalidParameter, "Invalid parameter.");
    }

    if (!(flag == Create || flag == (Create | SyncBlock) || flag == Overwrite
            || flag == (Overwrite | SyncBlock) || flag == Append
            || flag == (Append | SyncBlock) || flag == (Create | Overwrite)
            || flag == (Create | Overwrite | SyncBlock)
            || flag == (Create | Append)
            || flag == (Create | Append | SyncBlock))) {
        THROW(InvalidParameter, "Invalid flag.");
    }

    try {
        openInternal(fs, path, flag, permission, createParent, replication,
                     blockSize);
    } catch (...) {
        reset();
        throw;
    }
}

void OutputStreamImpl::computePacketChunkSize() {
    int chunkSizeWithChecksum = chunkSize + checksumSize;
    static const int packetHeaderSize = PacketHeader::GetPkgHeaderSize();
    chunksPerPacket =
        (packetSize - packetHeaderSize + chunkSizeWithChecksum - 1)
        / chunkSizeWithChecksum;
    chunksPerPacket = chunksPerPacket > 1 ? chunksPerPacket : 1;
    packetSize = chunksPerPacket * chunkSizeWithChecksum + packetHeaderSize;
    buffer.resize(chunkSize);
}

void OutputStreamImpl::initAppend() {
    FileStatus fileInfo;
    std::pair<shared_ptr<LocatedBlock>, shared_ptr<FileStatus> > lastBlockWithStatus;
    lastBlockWithStatus = filesystem->append(this->path);
    lastBlock = lastBlockWithStatus.first;

    if (lastBlockWithStatus.second) {
        fileInfo = *lastBlockWithStatus.second;
    } else {
        fileInfo = filesystem->getFileStatus(this->path.c_str());
    }

    closed = false;

    try {
        this->blockSize = fileInfo.getBlockSize();
        cursor = fileInfo.getLength();

        if (lastBlock) {
            isAppend = true;
            bytesWritten = lastBlock->getNumBytes();
            int64_t usedInLastBlock = fileInfo.getLength() % blockSize;
            int64_t freeInLastBlock = blockSize - usedInLastBlock;

            if (freeInLastBlock == this->blockSize) {
                THROW(HdfsIOException,
                      "OutputStreamImpl: the last block for file %s is full.",
                      this->path.c_str());
            }

            int usedInCksum = cursor % chunkSize;
            int freeInCksum = chunkSize - usedInCksum;

            if (usedInCksum > 0 && freeInCksum > 0) {
                /*
                 * if there is space in the last partial chunk, then
                 * setup in such a way that the next packet will have only
                 * one chunk that fills up the partial chunk.
                 */
                packetSize = 0;
                chunkSize = freeInCksum;
            } else {
                /*
                 * if the remaining space in the block is smaller than
                 * that expected size of of a packet, then create
                 * smaller size packet.
                 */
                packetSize =
                    packetSize < freeInLastBlock ?
                    packetSize : static_cast<int>(freeInLastBlock);
            }
        }
    } catch (...) {
        completeFile(false);
        reset();
        throw;
    }

    computePacketChunkSize();
}

void OutputStreamImpl::openInternal(shared_ptr<FileSystemInter> fs, const char * path,
                                    int flag, const Permission & permission, bool createParent,
                                    int replication, int64_t blockSize) {
    filesystem = fs;
    this->path = fs->getStandardPath(path);
    this->replication = replication;
    this->blockSize = blockSize;
    syncBlock = flag & SyncBlock;
    conf = shared_ptr < SessionConfig > (new SessionConfig(fs->getConf()));
    LOG(DEBUG2, "open file %s for %s", this->path.c_str(), (flag & Append ? "append" : "write"));
    packets.setMaxSize(conf->getPacketPoolSize());

    if (0 == replication) {
        this->replication = conf->getDefaultReplica();
    } else {
        this->replication = replication;
    }

    if (0 == blockSize) {
        this->blockSize = conf->getDefaultBlockSize();
    } else {
        this->blockSize = blockSize;
    }

    chunkSize = conf->getDefaultChunkSize();
    packetSize = conf->getDefaultPacketSize();
    heartBeatInterval = conf->getHeartBeatInterval();
    closeTimeout = conf->getCloseFileTimeout();

    if (packetSize < chunkSize) {
        THROW(InvalidParameter,
              "OutputStreamImpl: packet size %d is less than the chunk size %d.",
              packetSize, chunkSize);
    }

    if (0 != this->blockSize % chunkSize) {
        THROW(InvalidParameter,
              "OutputStreamImpl: block size %" PRId64 " is not the multiply of chunk size %d.",
              this->blockSize, chunkSize);
    }

    try {
        if (flag & Append) {
            if (!conf->getKmsUrl().empty()) {
                fileStatus = fs->getFileStatus(this->path.c_str());
                FileEncryptionInfo *fileEnInfo = fileStatus.getFileEncryption();
                if (fileStatus.isFileEncrypted()) {
                    if (cryptoCodec == NULL) {
                        auth = shared_ptr<RpcAuth> (
                                new RpcAuth(fs->getUserInfo(), RpcAuth::ParseMethod(conf->getKmsMethod())));
                        kcp = shared_ptr<KmsClientProvider> (
                                new KmsClientProvider(auth, conf));
                        cryptoCodec = shared_ptr<CryptoCodec> (
                                new CryptoCodec(fileEnInfo, kcp, conf->getCryptoBufferSize()));

                        int64_t file_length = fileStatus.getLength();
                        int ret = cryptoCodec->init(CryptoMethod::ENCRYPT, file_length);
                        if (ret < 0) {
                            THROW(HdfsIOException, "init CryptoCodec failed, file:%s", this->path.c_str());
                        }
                    }
                }
            }
            initAppend();
            LeaseRenewer::GetLeaseRenewer().StartRenew(filesystem);
            return;
        }
    } catch (const FileNotFoundException & e) {
        if (!(flag & Create)) {
            throw;
        }
    }

    assert((flag & Create) || (flag & Overwrite));
    fs->create(this->path, permission, flag, createParent, this->replication,
            this->blockSize);
    if (!conf->getKmsUrl().empty()) {
        fileStatus = fs->getFileStatus(this->path.c_str());
        FileEncryptionInfo *fileEnInfo = fileStatus.getFileEncryption();
        if (fileStatus.isFileEncrypted()) {
            if (cryptoCodec == NULL) {
                auth = shared_ptr<RpcAuth>(
                        new RpcAuth(fs->getUserInfo(), RpcAuth::ParseMethod(conf->getKmsMethod())));
                kcp = shared_ptr<KmsClientProvider>(
                        new KmsClientProvider(auth, conf));
                cryptoCodec = shared_ptr<CryptoCodec>(
                        new CryptoCodec(fileEnInfo, kcp, conf->getCryptoBufferSize()));

                int64_t file_length = fileStatus.getLength();
                assert(file_length == 0);
                int ret = cryptoCodec->init(CryptoMethod::ENCRYPT, file_length);
                if (ret < 0) {
                    THROW(HdfsIOException, "init CryptoCodec failed, file:%s", this->path.c_str());
                }
            }
        }
    }
    closed = false;
    computePacketChunkSize();
    LeaseRenewer::GetLeaseRenewer().StartRenew(filesystem);
}

/**
 * To append data to file.
 * @param buf the data used to append.
 * @param size the data size.
 */
void OutputStreamImpl::append(const char * buf, int64_t size) {
    LOG(DEBUG3, "append file %s size is %" PRId64 ", offset %" PRId64 " next pos %" PRId64, path.c_str(), size, cursor, size + cursor);

    if (NULL == buf || size < 0) {
        THROW(InvalidParameter, "Invalid parameter.");
    }

    checkStatus();

    try {
        appendInternal(buf, size);
    } catch (...) {
        setError(current_exception());
        throw;
    }
}

void OutputStreamImpl::appendInternal(const char * buf, int64_t size) {
    int64_t todo = size;
	std::string bufEncode;

    if (fileStatus.isFileEncrypted()) {
        //encrypt buf
        bufEncode = cryptoCodec->cipher_wrap(buf, size);
        buf = bufEncode.c_str();

    }
    while (todo > 0) {
        int batch = buffer.size() - position;
        batch = batch < todo ? batch : static_cast<int>(todo);

        /*
         * bypass buffer.
         */
        if (0 == position && todo >= static_cast<int64_t>(buffer.size())) {
            checksum->update(buf + size - todo, batch);
            appendChunkToPacket(buf + size - todo, batch);
            bytesWritten += batch;
            checksum->reset();
        } else {
            checksum->update(buf + size - todo, batch);
            memcpy(&buffer[position], buf + size - todo, batch);
            position += batch;

            if (position == static_cast<int>(buffer.size())) {
                appendChunkToPacket(&buffer[0], buffer.size());
                bytesWritten += buffer.size();
                checksum->reset();
                position = 0;
            }
        }

        todo -= batch;

        if (currentPacket
                && (currentPacket->isFull() || bytesWritten == blockSize)) {
            sendPacket(currentPacket);

            if (isAppend) {
                isAppend = false;
                chunkSize = conf->getDefaultChunkSize();
                packetSize = conf->getDefaultPacketSize();
                computePacketChunkSize();
            }

            if (bytesWritten == blockSize) {
                closePipeline();
            }
        }
    }

    cursor += size;
}

void OutputStreamImpl::appendChunkToPacket(const char * buf, int size) {
    assert(NULL != buf && size > 0);

    if (!currentPacket) {
        currentPacket = packets.getPacket(packetSize, chunksPerPacket, bytesWritten,
                                          nextSeqNo++, checksumSize);
    }

    currentPacket->addChecksum(checksum->getValue());
    currentPacket->addData(buf, size);
    currentPacket->increaseNumChunks();
}

void OutputStreamImpl::sendPacket(shared_ptr<Packet> packet) {
    if (!pipeline) {
        setupPipeline();
    }

    pipeline->send(currentPacket);
    currentPacket.reset();
    lastSend = steady_clock::now();
}

void OutputStreamImpl::setupPipeline() {
    assert(currentPacket);
#ifdef MOCK
    pipeline = stub->getPipeline();
#else
    pipeline = shared_ptr<Pipeline>(new PipelineImpl(isAppend, path.c_str(), *conf, filesystem,
                                    CHECKSUM_TYPE_CRC32C, conf->getDefaultChunkSize(), replication,
                                    currentPacket->getOffsetInBlock(), packets, lastBlock));
#endif
    lastSend = steady_clock::now();
    /*
     * start heart beat beat thread
     */
    /*if (heartBeatStop) {
        if (heartBeatSender.joinable()) {
            heartBeatSender.join();
        }

        heartBeatStop = false;
        heartBeatSender = thread(&OutputStreamImpl::heartBeatSenderRoutine, this);
    }*/
}

/**
 * Flush all data in buffer and waiting for ack.
 * Will block until get all acks.
 */
void OutputStreamImpl::flush() {
    LOG(DEBUG3, "flush file %s at offset %" PRId64, path.c_str(), cursor);
    checkStatus();

    try {
        flushInternal(false);
    } catch (...) {
        setError(current_exception());
        throw;
    }
}

void OutputStreamImpl::flushInternal(bool needSync) {
    if (lastFlushed == cursor && !needSync) {
        return;
    } else {
        lastFlushed = cursor;
    }

    if (position > 0) {
        appendChunkToPacket(&buffer[0], position);
    }

    /*
     * if the pipeline and currentPacket are both NULL,
     * that means the pipeline has been closed and no more data in buffer/packet.
     * already synced when closing pipeline.
     */
    if (!currentPacket && needSync && pipeline) {
        currentPacket = packets.getPacket(packetSize, chunksPerPacket, bytesWritten,
                                          nextSeqNo++, checksumSize);
    }

    lock_guard < mutex > lock(mut);

    if (currentPacket) {
        currentPacket->setSyncFlag(needSync);
        sendPacket(currentPacket);
    }

    if (pipeline) {
        pipeline->flush();
    }
}

/**
 * return the current file length.
 * @return current file length.
 */
int64_t OutputStreamImpl::tell() {
    checkStatus();
    return cursor;
}

/**
 * @ref OutputStream::sync
 */
void OutputStreamImpl::sync() {
    LOG(DEBUG3, "sync file %s at offset %" PRId64, path.c_str(), cursor);
    checkStatus();

    try {
        flushInternal(true);
    } catch (...) {
        setError(current_exception());
        throw;
    }
}

void OutputStreamImpl::completeFile(bool throwError) {
    steady_clock::time_point start = steady_clock::now();

    while (true) {
        try {
            bool success;
            success = filesystem->complete(path, lastBlock.get());

            if (success) {
                return;
            }
        } catch (HdfsIOException & e) {
            if (throwError) {
                NESTED_THROW(HdfsIOException,
                             "OutputStreamImpl: failed to complete file %s.",
                             path.c_str());
            } else {
                return;
            }
        }

        if (closeTimeout > 0) {
            steady_clock::time_point end = steady_clock::now();

            if (ToMilliSeconds(start, end) >= closeTimeout) {
                if (throwError) {
                    THROW(HdfsIOException,
                          "OutputStreamImpl: timeout when complete file %s, timeout interval %d ms.",
                          path.c_str(), closeTimeout);
                } else {
                    return;
                }
            }
        }

        try {
            sleep_for(milliseconds(400));
        } catch (...) {
        }
    }
}

/**
 * close the stream.
 */
void OutputStreamImpl::closePipeline() {
    lock_guard < mutex > lock(mut);

    if (!pipeline) {
        return;
    }

    if (currentPacket) {
        sendPacket(currentPacket);
    }

    currentPacket = packets.getPacket(packetSize, chunksPerPacket, bytesWritten, nextSeqNo++,
                                      checksumSize);

    if (syncBlock) {
        currentPacket->setSyncFlag(syncBlock);
    }

    lastBlock = pipeline->close(currentPacket);
    assert(lastBlock);
    currentPacket.reset();
    pipeline.reset();
    filesystem->fsync(path);
    bytesWritten = 0;
}

void OutputStreamImpl::close() {
    exception_ptr e;

    if (closed) {
        return;
    }

    try {
        //pipeline may be broken
        if (!lastError) {
            if (lastFlushed != cursor && position > 0) {
                appendChunkToPacket(&buffer[0], position);
            }

            if (lastFlushed != cursor && currentPacket) {
                sendPacket(currentPacket);
            }

            closePipeline();
            /*heartBeatStop = true;
             condHeartBeatSender.notify_all();

             if (heartBeatSender.joinable()) {
             heartBeatSender.join();
             }*/
            completeFile(true);
        }
    } catch (...) {
        e = current_exception();
    }

    LeaseRenewer::GetLeaseRenewer().StopRenew(filesystem);
    LOG(DEBUG3, "close file %s for write with length %" PRId64, path.c_str(), cursor);
    reset();

    if (e) {
        rethrow_exception(e);
    }
}

void OutputStreamImpl::reset() {
    blockSize = 0;
    bytesWritten = 0;
    checksum->reset();
    chunkSize = 0;
    chunksPerPacket = 0;
    closed = true;
    closeTimeout = 0;
    conf.reset();
    currentPacket.reset();
    cursor = 0;
    filesystem.reset();
    heartBeatInterval = 0;
    isAppend = false;
    lastBlock.reset();
    lastError = exception_ptr();
    lastFlushed = 0;
    nextSeqNo = 0;
    packetSize = 0;
    path.clear();
    pipeline.reset();
    position = 0;
    replication = 0;
    syncBlock = false;
}

std::string OutputStreamImpl::toString() {
    if (path.empty()) {
        return std::string("OutputStream for path ") + path;
    } else {
        return std::string("OutputStream (not opened)");
    }
}

/*void OutputStreamImpl::heartBeatSenderRoutine() {
    assert(heartBeatStop == false);

    while (!heartBeatStop) {
        try {
            unique_lock < mutex > lock(mut);
            condHeartBeatSender.wait_for(lock, milliseconds(1000));

            try {
                try {
                    if (pipeline
                            && ToMilliSeconds(lastSend, steady_clock::now())
                            >= heartBeatInterval) {
                        pipeline->send(shared_ptr < Packet > (new Packet()));
                        lastSend = steady_clock::now();
                    }
                } catch (...) {
                    NESTED_THROW(Hdfs::HdfsIOException, "Failed to send heart beat, path: %s",
                                 path.c_str());
                }
            } catch (...) {
                lastError = current_exception();
                throw;
            }
        } catch (const std::bad_alloc & e) {

             * keep quiet if we run out of memory, since writing log need memory,
             * that may cause the process terminated.

            break;
        } catch (const Hdfs::HdfsException & e) {
            LOG(LOG_ERROR, "Heart beat thread exit since %s",
                GetExceptionDetail(e));
        } catch (const std::exception & e) {
            LOG(LOG_ERROR, "Heart beat thread exit since %s",
                e.what());
        }
    }

    heartBeatStop = true;
}*/

}
}
