require('./utils.js');

var JobRunner = require('./job-runner.js');
var JobWatcher = require('./job-watcher.js');

var pwuid = require('pwuid');
var prompt = require('prompt');
var fs = require('fs');
var request = require('request');
var FormData = require('form-data');
var path = require('path');

var ansi = require('ansi');
var cursor = ansi(process.stdout);
var winston = require('winston');

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({}),
    new (winston.transports.File)({ level: 'debug', filename: 'asconsolelog.txt'} )
  ]
});

var Table = require('cli-table');



prompt.message = "Enter".red;
prompt.delimiter = " : ".yellow;

exports.setup = function() {
  logger.info("Setting up");
  var config = {};

  prompt.get([{
    description: 'ArchivesSpace Backend URL',
    name: 'backend_url',
    type: 'string',
    required: true,
  default: 'http://localhost:4567',
  }, {
    name: 'username',
    description: 'Your username',
    type: 'string',
    required: true,
  default: 'admin',
  }, {
    name: 'password',
    hidden: true,
  }], function(err, result) {

    var matches = result.backend_url.match(/^(.*):(\d+)$/);

    if (matches) {
      config.backend_host = matches[1];
      config.backend_port = matches[2];
    } else {
      config.backend_host = result.backend_url;
      config.backend_port = "80";
    }

    login(config,
          result.username,
          result.password);
  });
}

exports.argv = function(argv) {
  logger.debug(argv);
}

exports.ls = function(argv) {
  var dir = argv._.shift();

  if (!dir) dir = './';

  var dirState = path.join('./', dir, '.asstate');

  console.log(dirState);
  if (fs.existsSync(dirState)) {
    var table = new Table({
      head: ['File', 'Job ID', 'Status', 'Reason'],
      colWidths: [20, 10, 10, 60]
    });

    var fileStates = fs.readFileSync(dirState).toString().split("\n");
    fileStates.each(function(fileState) {
      var matches = fileState.match(/^([^:]*):(.*)$/);
      if (!matches) return;
      var state = JSON.parse(matches[2]);
      var filename = matches[1];
      table.push([filename, "0", state.status, "TBD"]);
    });

    console.log(table.toString());
                    
  } else {
    console.log("Nothing to see here");
  }
};


exports.jobs = function(argv) {

  var action = argv._.shift();

  if (action == 'create') {
    var runner = new JobRunner({
      dir: argv['dir'],
      import_type: argv['type'],
      api_callback: function(formData, callback) {
        doPostForm("/repositories/:repo_id/jobs", formData, function(err, res, body) {
        if (err) throw(err);

        callback(JSON.parse(body));
        });
      },
      watcher_callback: function(job, callback) {
        doGet(job.uri, function(err, res, body) {
          json = JSON.parse(body);
          callback(json);
        });
      }

    });

    runner.run(function() {
      console.log("Done");
    });

  } else {
    doGet("/repositories/:repo_id/jobs?page=1", function(err, res, body) {
      json = JSON.parse(body);
      var table = buildJobsTable(json.results);
      console.log(table.toString());
    });
  }
}


exports.repositories = function() {
  doGet("/repositories", function(err, res, body) {
    var table = new Table({
      head: ['ID', 'URL', 'Name', 'Description'],
      colWidths: [10, 20, 20, 40]
    });

    var repos = JSON.parse(body);

    repos.each(function(repo) {
      repo.id = repo.uri.match(/\/(\d+)$/)[1];
      var row = [repo.id, repo.uri, repo.name, repo.description];
      row.replace_undefined("(none)");
      logger.debug(row);
      table.push(row);
    });

    console.log(table.toString());

    prompt.get([{
      description: 'Select working repository',
      name: 'active_repo',
      type: 'number',
      required: false,
    }], function (err, result) {
      if (result.active_repo) {
        setRepo(result.active_repo, function(id) {
          logger.log('debug', 'Set active repo: %d', id);
        });
      }
    });
  });
}


function login(config, config_file, user, password) {

  var form = {form: {password: password}};
  var session = "";

  request.post(config.backend_host + ":" + config.backend_port + "/users/" + user + "/login", form, function(error, response, body) {
    json = JSON.parse(body);
    console.log(json);

    config.session = json.session;

    saveConfig(config_file, config);
  });
}

function configPath() {
  return pwuid().dir + '/.asconsole';
}


function saveConfig(config) {
  fs.writeFile(configPath(), JSON.stringify(config), function(err) {
    if (err) {
      console.log("Error " + err);
    } else {
      console.log("Settings saved");
      }
  });
}


function doPostForm(path, form, callback) {
  fs.readFile(configPath(), function(err, data) {
    config = JSON.parse(data);

    if (config.active_repo) {
      path = path.replace(":repo_id", config.active_repo);
    }

    var opts = {
      url: config.backend_host + ":" + config.backend_port + path,
      headers: {
        'X-ArchivesSpace-Session': config.session
      }
    };

    form.getLength(function(err, length) {
      if (err) throw err;

      var r = request.post(opts, callback);
      r._form = form;
      r.setHeader('content-length', length);
    });

  });
}

function doGet(path, callback) {
  fs.readFile(configPath(), function(err, data) {
    config = JSON.parse(data);

    if (config.active_repo) {
      path = path.replace(":repo_id", config.active_repo);
    }

    var opts = {
      url: config.backend_host + ":" + config.backend_port + path,
      headers: {
        'X-ArchivesSpace-Session': config.session
      }
    };

    request(opts, callback);
  });
}

function setRepo(id, callback) {
  fs.readFile(configPath(), function(err, data) {
    config = JSON.parse(data);
    config.active_repo = id;
    saveConfig(config);
    callback(id);
  });
}
  

function buildJobsTable(jobs) {
  var table = new Table({
    head: ['ID', 'Status', 'Type', 'Files', 'Submitted'],
    colWidths: [10, 20, 20, 50, 20]
  });

  jobs.each(function(job) {
    job.id = job.uri.match(/\/(\d+)$/)[1];
    var row = [job.id, job.status, job.import_type, job.filenames.join("\n"), job.time_submitted]
    row.replace_undefined("(none)");
    
    logger.debug(row.join("--"));
    table.push(row);
  });

  return table;
}
