#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <stdexcept>
using namespace std;

#include "util.h"
#include "person.h"

ostream & operator<<(ostream & os, vector<int> & v) {
    os << "[";
    for(unsigned int i = 0; i < v.size(); i++) {
        os << v[i];
        if(i != v.size() - 1) {
            os << ", ";
        }
    }
    os << "]";
    return os;
}

vector<string> tokenize(const string & str, const string & delimiters) {
    vector<string> tokens;
    // Skip delimiters at beginning.
    string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
    string::size_type pos  = str.find_first_of(delimiters, lastPos);
    while (string::npos != pos || string::npos != lastPos)
    {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
    return tokens;
}

vector<person> parse_file(string filename) {
    ifstream inputs(filename.c_str());
    if(inputs.good()) {
        vector<person> people;
        string line;
        int age;

        while(getline(inputs, line)) {
            vector<string> tokens = tokenize(line, ",");
            string name = tokens[0];
            string age_s = tokens[1];

            //clean up name
            vector<string> name_tokens = tokenize(name, " ");
            name.clear();
            for(unsigned int i = 0; i < name_tokens.size(); i++) {
                name += name_tokens[i];
                if(i != name_tokens.size() - 1) {
                    name += " ";
                }
            }

            // parse an int
            stringstream age_parser(age_s);
            age_parser >> age;
            people.push_back(person(name, age));
        }

        return people;
    }
    else {
        throw runtime_error("Input file was not good; please verify.");
    }
}

void save_file(string filename, const vector<person> & people) {
    ofstream output_file(filename.c_str());
    for(auto p: people) {
        output_file << p << endl;
    }
}
