// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_
#define NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include <vector>

#include "base/files/file_util.h"
#include "base/strings/string_split.h"

// Class to handle loadtime measure related urls, which all start with testing
// The in memory server has a singleton object of this class. It includes a
// html file containing javascript to go through a list of urls and upload the
// loadtime. The users can modify urls.txt to define the urls they want to
// measure and start with downloading the html file from browser.
class LoadtimeMeasurement {
 public:
  LoadtimeMeasurement(const std::string& urls_file,
                      const std::string& pageload_html_file)
      : num_urls_(0), pageload_html_file_(pageload_html_file) {
    std::string urls_string;
    base::ReadFileToString(urls_file, &urls_string);
    base::SplitString(urls_string, '\n', &urls_);
    num_urls_ = urls_.size();
  }

  // This is the entry function for all the loadtime measure related urls
  // It handles the request to html file, get_total_iteration to get number
  // of urls in the urls file, get each url, report the loadtime for
  // each url, and the test is completed.
  void ProcessRequest(const std::string& uri, std::string& output) {
    // remove "/testing/" from uri to get the action
    std::string action = uri.substr(9);
    if (pageload_html_file_.find(action) != std::string::npos) {
      base::ReadFileToString(pageload_html_file_, &output);
      return;
    }
    if (action.find("get_total_iteration") == 0) {
      char buffer[16];
      snprintf(buffer, sizeof(buffer), "%d", num_urls_);
      output.append(buffer, strlen(buffer));
      return;
    }
    if (action.find("geturl") == 0) {
      size_t b = action.find_first_of('=');
      if (b != std::string::npos) {
        int num = atoi(action.substr(b + 1).c_str());
        if (num < num_urls_) {
          output.append(urls_[num]);
        }
      }
      return;
    }
    if (action.find("test_complete") == 0) {
      for (std::map<std::string, int>::const_iterator it = loadtimes_.begin();
           it != loadtimes_.end();
           ++it) {
        LOG(INFO) << it->first << " " << it->second;
      }
      loadtimes_.clear();
      output.append("OK");
      return;
    }
    if (action.find("record_page_load") == 0) {
      std::vector<std::string> query;
      base::SplitString(action, '?', &query);
      std::vector<std::string> params;
      base::SplitString(query[1], '&', &params);
      std::vector<std::string> url;
      std::vector<std::string> loadtime;
      base::SplitString(params[1], '=', &url);
      base::SplitString(params[2], '=', &loadtime);
      loadtimes_[url[1]] = atoi(loadtime[1].c_str());
      output.append("OK");
      return;
    }
  }

 private:
  int num_urls_;
  std::vector<std::string> urls_;
  std::map<std::string, int> loadtimes_;
  const std::string pageload_html_file_;
};

#endif  // NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H_
