# Copyright 2016 Google Inc. All Rights Reserved.
#
# 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.


def generate_files(injection_graph, generate_runtime_bench_code, use_normalized_component=False):
    if use_normalized_component:
        assert not generate_runtime_bench_code

    file_content_by_name = dict()

    for node_id in injection_graph.nodes_iter():
        file_content_by_name['component%s.h' % node_id] = _generate_component_header(node_id)
        file_content_by_name['component%s.cpp' % node_id] = _generate_component_source(node_id, injection_graph.successors(node_id))

    [toplevel_node] = [node_id
                       for node_id in injection_graph.nodes_iter()
                       if not injection_graph.predecessors(node_id)]
    file_content_by_name['main.cpp'] = _generate_main(toplevel_node, generate_runtime_bench_code)

    return file_content_by_name

def _get_component_type(component_index):
    return 'fruit::Component<Interface{component_index}>'.format(**locals())

def _generate_component_header(component_index):
    component_type = _get_component_type(component_index)
    template = """
#ifndef COMPONENT{component_index}_H
#define COMPONENT{component_index}_H

#include <fruit/fruit.h>

// Example include that the code might use
#include <vector>

struct Interface{component_index} {{
  virtual ~Interface{component_index}() = default;
}};

{component_type} getComponent{component_index}();

#endif // COMPONENT{component_index}_H
"""
    return template.format(**locals())

def _generate_component_source(component_index, deps):
    include_directives = ''.join(['#include "component%s.h"\n' % index for index in deps + [component_index]])

    fields = ''.join(['Interface%s& x%s;\n' % (dep, dep)
                      for dep in deps])

    component_deps = ', '.join(['Interface%s& x%s' % (dep, dep)
                                for dep in deps])
    param_initializers = ', '.join('x%s(x%s)' % (dep, dep)
                                   for dep in deps)
    if param_initializers:
        param_initializers = ': ' + param_initializers

    install_expressions = ''.join(['        .install(getComponent%s)\n' % dep for dep in deps])

    component_type = _get_component_type(component_index)

    template = """
{include_directives}

namespace {{
struct X{component_index} : public Interface{component_index} {{
  {fields}

  INJECT(X{component_index}({component_deps})) {param_initializers} {{}}

  virtual ~X{component_index}() = default;
}};
}}

"""

    template += """
{component_type} getComponent{component_index}() {{
    return fruit::createComponent(){install_expressions}
        .bind<Interface{component_index}, X{component_index}>();
}}
"""

    return template.format(**locals())

def _generate_main(toplevel_component, generate_runtime_bench_code):
    if generate_runtime_bench_code:
        template = """
#include "component{toplevel_component}.h"

#include <ctime>
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <chrono>

using namespace std;

fruit::Component<> getEmptyComponent() {{
  return fruit::createComponent();
}}

int main(int argc, char* argv[]) {{
  if (argc != 2) {{
    std::cout << "Need to specify num_loops as argument." << std::endl;
    exit(1);
  }}
  size_t num_loops = std::atoi(argv[1]);
  
  std::chrono::high_resolution_clock::time_point start_time = std::chrono::high_resolution_clock::now();
  for (size_t i = 0; i < 1 + num_loops/100; i++) {{
    fruit::NormalizedComponent<Interface{toplevel_component}> normalizedComponent(getComponent{toplevel_component});
    (void)normalizedComponent;
  }}
  double componentNormalizationTime = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_time).count();

  fruit::NormalizedComponent<Interface{toplevel_component}> normalizedComponent(getComponent{toplevel_component});
    
  start_time = std::chrono::high_resolution_clock::now();
  for (size_t i = 0; i < num_loops; i++) {{
    fruit::Injector<Interface{toplevel_component}> injector(normalizedComponent, getEmptyComponent);
    injector.get<std::shared_ptr<Interface{toplevel_component}>>();
  }}
  double perRequestTime = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_time).count();

  std::cout << std::fixed;
  std::cout << std::setprecision(15);
  std::cout << "componentNormalizationTime = " << componentNormalizationTime * 100 / num_loops << std::endl;
  std::cout << "Total for setup            = " << componentNormalizationTime * 100 / num_loops << std::endl;
  std::cout << "Total per request          = " << perRequestTime / num_loops << std::endl;
  return 0;
}}
    """
    else:
        template = """
#include "component{toplevel_component}.h"

#include <iostream>

fruit::Component<> getEmptyComponent() {{
  return fruit::createComponent();
}}

int main(void) {{
  fruit::NormalizedComponent<Interface{toplevel_component}> normalizedComponent(getComponent{toplevel_component});
  fruit::Injector<Interface{toplevel_component}> injector(normalizedComponent, getEmptyComponent);
  injector.get<std::shared_ptr<Interface{toplevel_component}>>();
  std::cout << "Hello, world" << std::endl;
  return 0;
}}
    """

    return template.format(**locals())
