// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/config_file_stream.h"

#ifdef OS_WIN
#include <windows.h>
#endif  // OS_WIN

#include <cstring>
#include <map>
#include <sstream>
#include "base/file_stream.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/port.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/util.h"

namespace mozc {

namespace {

static const char kSystemPrefix[] = "system://";
static const char kUserPrefix[]   = "user://";
static const char kFilePrefix[]   = "file://";
static const char kMemoryPrefix[] = "memory://";

struct FileData {
  const char *name;
  const char *data;
  size_t size;
};

string RemovePrefix(const char *prefix, const string &filename) {
  const size_t size = strlen(prefix);
  if (filename.size() < size) {
    return "";
  }
  return filename.substr(size, filename.size() - size);
}

class OnMemoryFileMap {
 public:
  string get(const string &key) const {
    map<string, string>::const_iterator it = map_.find(key);
    if (it != map_.end()) {
      return it->second;
    }
    return string("");
  }

  void set(const string &key, const string &value) {
    map_[key] = value;
  }

  void clear() {
    map_.clear();
  }

 private:
  map<string, string> map_;
};

#include "base/config_file_stream_data.h"
}  // namespace

istream *ConfigFileStream::Open(const string &filename,
                                ios_base::openmode mode) {
  // system://foo.bar.txt
  if (Util::StartsWith(filename, kSystemPrefix)) {
    const string new_filename = RemovePrefix(kSystemPrefix, filename);
    for (size_t i = 0; i < arraysize(kFileData); ++i) {
      if (new_filename == kFileData[i].name) {
        istringstream *ifs = new istringstream(
            string(kFileData[i].data, kFileData[i].size), mode);
        CHECK(ifs);
        if (ifs->good()) {
          return ifs;
        }
        delete ifs;
        return NULL;
      }
    }
  // user://foo.bar.txt
  } else if (Util::StartsWith(filename, kUserPrefix)) {
    const string new_filename =
        FileUtil::JoinPath(SystemUtil::GetUserProfileDirectory(),
                           RemovePrefix(kUserPrefix, filename));
    InputFileStream *ifs = new InputFileStream(new_filename.c_str(), mode);
    CHECK(ifs);
    if (ifs->good()) {
      return ifs;
    }
    delete ifs;
    return NULL;
  // file:///foo.map
  } else if (Util::StartsWith(filename, kFilePrefix)) {
    const string new_filename = RemovePrefix(kFilePrefix, filename);
    InputFileStream *ifs = new InputFileStream(new_filename.c_str(), mode);
    CHECK(ifs);
    if (ifs->good()) {
      return ifs;
    }
    delete ifs;
    return NULL;
  } else if (Util::StartsWith(filename, kMemoryPrefix)) {
    istringstream *ifs = new istringstream(
        Singleton<OnMemoryFileMap>::get()->get(filename), mode);
    CHECK(ifs);
    if (ifs->good()) {
      return ifs;
    }
    delete ifs;
    return NULL;
  } else {
    LOG(WARNING) << filename << " has no prefix. open from localfile";
    InputFileStream *ifs = new InputFileStream(filename.c_str(), mode);
    CHECK(ifs);
    if (ifs->good()) {
      return ifs;
    }
    delete ifs;
    return NULL;
  }

  return NULL;
}

bool ConfigFileStream::AtomicUpdate(const string &filename,
                                    const string &new_binary_contens) {
  if (Util::StartsWith(filename, kMemoryPrefix)) {
    Singleton<OnMemoryFileMap>::get()->set(filename, new_binary_contens);
    return true;
  } else if (Util::StartsWith(filename, kSystemPrefix)) {
    LOG(ERROR) << "Cannot update system:// files.";
    return false;
  }
  // We should save the new config first,
  // as we may rewrite the original config according to platform.
  // The original config should be platform independent.
  const string real_filename = GetFileName(filename);
  if (real_filename.empty()) {
    return false;
  }

  const string tmp_filename = real_filename + ".tmp";
  {
    OutputFileStream ofs(tmp_filename.c_str(), ios::out | ios::binary);
    if (!ofs.good()) {
      LOG(ERROR) << "cannot open " << tmp_filename;
      return false;
    }
    ofs << new_binary_contens;
  }

  if (!FileUtil::AtomicRename(tmp_filename, real_filename)) {
    LOG(ERROR) << "FileUtil::AtomicRename failed";
    return false;
  }

#ifdef OS_WIN
  // If file name doesn't end with ".db", the file
  // is more likely a temporary file.
  if (!Util::EndsWith(real_filename, ".db")) {
    // TODO(yukawa): Provide a way to
    // integrate ::SetFileAttributesTransacted with
    // AtomicRename.
    if (!FileUtil::HideFile(real_filename)) {
      LOG(ERROR) << "Cannot make hidden: " << real_filename
                 << " " << ::GetLastError();
    }
  }
#endif  // OS_WIN
  return true;
}

string ConfigFileStream::GetFileName(const string &filename) {
  if (Util::StartsWith(filename, kSystemPrefix) ||
      Util::StartsWith(filename, kMemoryPrefix)) {
    return "";
  } else if (Util::StartsWith(filename, kUserPrefix)) {
    return FileUtil::JoinPath(SystemUtil::GetUserProfileDirectory(),
                              RemovePrefix(kUserPrefix, filename));
  } else if (Util::StartsWith(filename, kFilePrefix)) {
    return RemovePrefix(kUserPrefix, filename);
  } else {
    LOG(WARNING) << filename << " has no prefix. open from localfile";
    return filename;
  }
  return "";
}

void ConfigFileStream::ClearOnMemoryFiles() {
  Singleton<OnMemoryFileMap>::get()->clear();
}
}  // namespace mozc
