/*
 * Copyright 2010 Google Inc.
 *
 * Licensed 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.
 */

// Author: sligocki@google.com (Shawn Ligocki)

#include "net/instaweb/rewriter/public/file_input_resource.h"

#include "base/logging.h"
#include "net/instaweb/http/public/http_value.h"
#include "net/instaweb/rewriter/cached_result.pb.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/server_context.h"
#include "pagespeed/kernel/base/file_system.h"
#include "pagespeed/kernel/base/message_handler.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/http/content_type.h"
#include "pagespeed/kernel/http/http_names.h"
#include "pagespeed/kernel/http/response_headers.h"

namespace {

const int64 kTimestampUnset = 0;

}  // namespace

namespace net_instaweb {

FileInputResource::FileInputResource(const RewriteDriver* driver,
                                     const ContentType* type, StringPiece url,
                                     StringPiece filename)
    : Resource(driver, type),
      url_(url.data(), url.size()),
      filename_(filename.data(), filename.size()),
      last_modified_time_sec_(kTimestampUnset),
      load_from_file_cache_ttl_ms_(
          driver->options()->load_from_file_cache_ttl_ms()),
      load_from_file_ttl_set_(
          driver->options()->load_from_file_cache_ttl_ms_was_set()) {
}

FileInputResource::~FileInputResource() {
}

// File input resources don't have expirations, we assume that the resource
// is valid as long as the FileInputResource lives.
bool FileInputResource::IsValidAndCacheable() const {
  // File is statted in RewriteContext::IsInputValid(). After which it's
  // status should be set to kOK.
  return response_headers_.status_code() == HttpStatus::kOK;
}

void FileInputResource::FillInPartitionInputInfo(
    HashHint include_content_hash, InputInfo* input) {
  CHECK(loaded());
  input->set_type(InputInfo::FILE_BASED);
  if (last_modified_time_sec_ == kTimestampUnset) {
    LOG(DFATAL) << "We should never have populated FileInputResource without "
        "a timestamp for " << filename_;

    // Resources can in theory be preloaded via HTTP cache, in which
    // case we'll have loaded() == true, but last_modified_time_sec_
    // unset.  We should be preventing this at a higher level because
    // FileInputResource::UseHttpCache returns false.  But we'll
    // defensively fill in the timestamp anyway in production.
    FileSystem* file_system = server_context_->file_system();
    if (!file_system->Mtime(filename_, &last_modified_time_sec_,
                            server_context()->message_handler())) {
      LOG(DFATAL) << "Could not get last_modified_time_ for file " << filename_;
    }
  }

  input->set_last_modified_time_ms(last_modified_time_sec_ * Timer::kSecondMs);
  input->set_filename(filename_);
  // If the file is valid and we are using a filesystem metadata cache, save
  // the hash of the file's contents for subsequent storing into it (the cache).
  if (IsValidAndCacheable() &&
      server_context_->filesystem_metadata_cache() != NULL) {
    input->set_input_content_hash(ContentsHash());
  }
}

// TODO(sligocki): Is this reasonable? People might want custom headers.
//
// For example, Content-Type is set solely by file extension and will not
// be set if the extension is unknown :/
//
// Date, Last-Modified and Cache-Control headers are set to support an
// implicit 5 min cache lifetime (for sync flow).
void FileInputResource::SetDefaultHeaders(const ContentType* content_type,
                                          ResponseHeaders* header,
                                          MessageHandler* handler) {
  header->set_major_version(1);
  header->set_minor_version(1);
  header->SetStatusAndReason(HttpStatus::kOK);
  header->RemoveAll(HttpAttributes::kContentType);
  if (content_type == NULL) {
    handler->Message(kError, "Loaded resource with no Content-Type %s",
                     url_.c_str());
  } else {
    header->Add(HttpAttributes::kContentType, content_type->mime_type());
  }
  // Note(sligocki): We are setting these to get FileInputResources
  // automatically cached for 5 minutes on the sync pathway. We could
  // probably remove it once we kill the sync pathway.
  int64 cache_ttl_ms;
  if (load_from_file_ttl_set_) {
    cache_ttl_ms = load_from_file_cache_ttl_ms_;
  } else {
    cache_ttl_ms = header->implicit_cache_ttl_ms();
  }
  header->SetDateAndCaching(server_context_->timer()->NowMs(), cache_ttl_ms);
  header->SetLastModified(last_modified_time_sec_ * Timer::kSecondMs);
  header->ComputeCaching();
}

// Note: We do not save this resource to the HttpCache, so it will be
// reloaded for every request.
void FileInputResource::LoadAndCallback(
    NotCacheablePolicy not_cacheable_policy,
    const RequestContextPtr& request_context,
    AsyncCallback* callback) {
  MessageHandler* handler = server_context()->message_handler();
  if (!loaded()) {
    // Load the file from disk.  Make sure we correctly read a timestamp
    // before loading the file.  A failure (say due to EINTR) on the
    // timestamp read could leave us with populated metadata and
    // an unset timestamp.
    //
    // TODO(jmarantz): it would be much better to use fstat on the
    // same file-handle we use for reading, rather than doing two
    // distinct file lookups, which is both slower and can introduce
    // skew.
    FileSystem* file_system = server_context_->file_system();
    if (file_system->Mtime(filename_, &last_modified_time_sec_, handler) &&
        (last_modified_time_sec_ != kTimestampUnset) &&
        file_system->ReadFile(filename_.c_str(), &value_, handler)) {
      SetDefaultHeaders(type_, &response_headers_, handler);
      value_.SetHeaders(&response_headers_);
    } else {
      value_.Clear();
      response_headers_.Clear();
      last_modified_time_sec_ = kTimestampUnset;
    }
  }
  callback->Done(false /* lock_failure */, loaded());
}

}  // namespace net_instaweb
