/*
 * 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 "write_file.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>

#include "common/config/config.h"
#include "common/logger/elog.h"
#include "utils/errno_define.h"

#ifdef _WIN32
int fsync(int);
#endif

using namespace common;

namespace storage {

#ifndef LIBTSFILE_SDK
int WriteFile::create(const FileID& file_id, int flags, mode_t mode) {
    if (fd_ > 0) {
        // log_err("file already opened, fd=%d", fd_);
        ASSERT(false);
        return E_ALREADY_EXIST;
    }
    file_id_ = file_id;
    path_ = get_file_path_from_file_id(file_id_);
    return do_create(flags, mode);
}
#endif

int WriteFile::create(const std::string& file_path, int flags, mode_t mode) {
    if (fd_ > 0) {
        // log_err("file already opened, fd=%d", fd_);
        ASSERT(false);
        return E_ALREADY_EXIST;
    }
    path_ = file_path;
    return do_create(flags, mode);
}

int WriteFile::do_create(int flags, mode_t mode) {
    int ret = E_OK;
    // TODO make sure no same file exists
    fd_ = ::open(path_.c_str(), flags, mode);
    if (fd_ < 0) {
        // log_err("open file error, path=%s, errno=%d", path_.c_str(), errno);
        ret = E_FILE_OPEN_ERR;
    } else {
    }
    return ret;
}

int WriteFile::write(const char* buf, uint32_t len) {
    ASSERT(fd_ > 0);

#if 0  // DEBUG_SE
    struct stat statbuf;
    if (fstat(fd_, &statbuf) < 0) {
      perror("fstat");
      ASSERT(false);
    }
    printf("writer buffer(%u bytes) to file at %zu\n", len, statbuf.st_size);
    for (uint32_t i = 0; i < len;) {
      printf("0x%02x ", (uint8_t)buf[i]);
      if ((++i) % 16 == 0) {
        printf("\n");
      }
    }
    printf("\n");
#endif

    int ret = E_OK;
    uint32_t write_done = 0;
    while (write_done < len && IS_SUCC(ret)) {
        int32_t cur_write = ::write(fd_, buf + write_done, len - write_done);
        if (cur_write < 0) {
            ret = E_FILE_WRITE_ERR;
            // log_err("file writer error, path=%s, error=%d", path_.c_str(),
            // errno);
        } else {
            write_done += cur_write;
        }
    }
    return ret;
}

int WriteFile::sync() {
    ASSERT(fd_ > 0);
    if (::fsync(fd_) < 0) {
        // log_err("file fsync error, path=%s, errno=%d", path_.c_str(), errno);
        return E_FILE_SYNC_ERR;
    }
    return E_OK;
}

int WriteFile::close() {
    ASSERT(fd_ > 0);
    if (::close(fd_) < 0) {
#ifdef DEBUG_SE
        std::cout << "failed to close " << path_ << " errorno " << errno
                  << std::endl;
#endif
        // log_err("file close error, path=%s, errno=%d", path_.c_str(), errno);
        return E_FILE_CLOSE_ERR;
    }
    fd_ = -1;
#ifdef DEBUG_SE
    std::cout << "close finish" << std::endl;
#endif
    return E_OK;
}

}  // end namespace storage

#ifdef _WIN32
int fsync(int fd) { return _commit(fd); }
#endif
