#include "ntfsmftentry.hh"

#include <stdio.h>
#include <assert.h>
#include <inttypes.h>
#include <iostream>
#include <vector>

NTFSMFTEntry::NTFSMFTEntry () :
   Res (-1)
{  
  Resident.filename = "";
  Resident.length = 0;
  Resident.offsetDATAattr = 0;
  Resident.entryLocation = 0;
  Resident.offsetInEntry = 0;
    
  NonResident.filename = "";
  NonResident.length = 0;
  NonResident.length = 0;
  NonResident.offsetDATAattr = 0;
  NonResident.clusters.clear();
  NonResident.segs.clear();
  NonResident.parentMFTentry = 0; // if -1, hasn't been updated
  NonResident.name_type = 0; // Can I do this?
  NonResident.alloc = 0; // set to not allocated
  NonResident.inUse = 0; // set to not in use
  NonResident.compressed = 0; // set to not in use
  NonResident.nlink = 0;
  NonResident.ownerID = 0;
  NonResident.sequenceValue = 0;  // if -1, hasn't been updated
  NonResident.fixupSignature = 0; // if -1, not yet set
  NonResident.offsetFileNameAttr = 0;
  NonResident.runlistOffset = 0;
  NonResident.ctime = 0;
  NonResident.atime = 0;
  NonResident.crtime = 0;
  NonResident.mtime = 0;
  NonResident.ownerID = 0;
}

NTFSMFTEntry::~NTFSMFTEntry() {}

void NTFSMFTEntry::set_resVnonres ( int test ) {
  // Resident == 0
  // NonResident == 1
  Res = test;
}

void NTFSMFTEntry::set_filename (std::string name) {
  if ( Res == 0 ) {
    Resident.filename = name;
  } else if (Res == 1) {
    NonResident.filename = name;
  } else {
    throw 5;
  }
}

std::string NTFSMFTEntry::get_filename () {
  if ( Res == 0 ) {
    return Resident.filename;
  } else if (Res == 1) {
    return NonResident.filename;
  } else {
    throw 6;
  }
}

void NTFSMFTEntry::set_length (int64_t l) {
  if ( Res == 0 ) {
    Resident.length = l;
  } else if ( Res == 1 ) {
    NonResident.length = l;
  } else {
    throw 3;
  }
}

int64_t NTFSMFTEntry::get_length () {
  if ( Res == 0 ) {
    return Resident.length;
  } else if (Res == 1) {
    return NonResident.length;
  } else {
    throw 4;
  }
}

void NTFSMFTEntry::set_initializedSize ( int64_t size ) {
  NonResident.initializedSize = size;
}

int64_t  NTFSMFTEntry::get_initializedSize () {
  return NonResident.initializedSize;
}

void NTFSMFTEntry::set_entryLocation ( int64_t location ) {
  if ( Res == 0 ) {
    Resident.entryLocation = location;
  } else {
    throw 8;
  }
}

int64_t NTFSMFTEntry::get_entryLocation () {
  return Resident.entryLocation;
}

void NTFSMFTEntry::set_offsetInEntry ( int64_t offset ) {
  if ( Res == 0 ) {
    Resident.offsetInEntry = offset;
  } else {
    throw 7;
  }
}

int64_t NTFSMFTEntry::get_offsetInEntry () {
  return Resident.offsetInEntry;
}

void NTFSMFTEntry::set_offsetDATAattr ( int64_t offset ) {
  if ( Res == 0 ) {
    Resident.offsetDATAattr = offset;
  } else if ( Res == 1 ) {
    NonResident.offsetDATAattr = offset;
  } else {
    throw 9;
  }
}

int64_t NTFSMFTEntry::get_offsetDATAattr () {
  if ( Res == 0 ) {
    return Resident.offsetDATAattr;
  } else if ( Res == 1 ) {
    return NonResident.offsetDATAattr;
  } else {
    throw 10;
  }
}

void NTFSMFTEntry::set_clusters ( std::vector<int64_t> clusters ) {
  NonResident.clusters = clusters;
}

// not used??
void NTFSMFTEntry::push_back (int64_t cluster) {
	NonResident.clusters.push_back (cluster);
}

void NTFSMFTEntry::printClusters () {
	for (unsigned int i = 0; i < NonResident.clusters.size(); i++) {
		std::cout << std::dec << NonResident.clusters.at(i) << " ";
    //<< std:: endl;
	}
}

void NTFSMFTEntry::set_seglist ( seglist segments ) {
  NonResident.segs = segments;
}

// parent MFT entry
void NTFSMFTEntry::set_parentMFTentry ( int64_t parent ) {
  NonResident.parentMFTentry = parent;
}

int64_t NTFSMFTEntry::get_parentMFTentry () {
  return NonResident.parentMFTentry;
}

// name type
void NTFSMFTEntry::set_name_type ( char type ) {
  NonResident.name_type = type;
}

char NTFSMFTEntry::get_name_type () {
  return NonResident.name_type;
}
 
// allocation status
void NTFSMFTEntry::set_alloc ( int status ) {
  NonResident.alloc = status;
}

int NTFSMFTEntry::get_alloc () {
  return NonResident.alloc;
}

// in use
void NTFSMFTEntry::set_inUse ( int use ) {
  NonResident.inUse = use;
}

int NTFSMFTEntry::get_inUse () {
  return NonResident.inUse;
}

// in use
void NTFSMFTEntry::set_compressed ( int compressed ) {
  NonResident.compressed = compressed;
}

int NTFSMFTEntry::get_compressed () {
  return NonResident.compressed;
}

// number of links
void NTFSMFTEntry::set_nlink ( int num ) {
  NonResident.nlink = num;
}

int NTFSMFTEntry::get_nlink () {
  return NonResident.nlink;
}

// owner ID
void NTFSMFTEntry::set_ownerID ( int ID ) {
  NonResident.ownerID = ID;
}

int NTFSMFTEntry::get_ownerID () {
  return NonResident.ownerID;
}

// sequence value
void NTFSMFTEntry::set_sequenceValue ( int64_t sequence ) {
  NonResident.sequenceValue = sequence;
}

int64_t NTFSMFTEntry::get_sequenceValue () {
  return NonResident.sequenceValue;
}

// times
void NTFSMFTEntry::set_ctime ( uint64_t time ) {
  NonResident.ctime = time;
}

uint64_t NTFSMFTEntry::get_ctime () {
  return NonResident.ctime;
}

void NTFSMFTEntry::set_atime ( uint64_t time ) {
  NonResident.atime = time;
}

uint64_t NTFSMFTEntry::get_atime () {
  return NonResident.atime;
}

void NTFSMFTEntry::set_crtime ( uint64_t time ) {
  NonResident.crtime = time;
}

uint64_t NTFSMFTEntry::get_crtime () {
  return NonResident.crtime;
}

void NTFSMFTEntry::set_mtime ( uint64_t time ) {
  NonResident.mtime = time;
}

uint64_t NTFSMFTEntry::get_mtime () {
  return NonResident.mtime;
}

void NTFSMFTEntry::set_fixupSignature ( uint64_t signature ) {
  NonResident.fixupSignature = signature;
}

uint64_t NTFSMFTEntry::get_fixupSignature () {
  return NonResident.fixupSignature;
}

void NTFSMFTEntry::set_offsetFileNameAttr ( int64_t offset ) {
  NonResident.offsetFileNameAttr = offset;
}

int64_t NTFSMFTEntry::get_offsetFileNameAttr () {
  return NonResident.offsetFileNameAttr;
}

void NTFSMFTEntry::set_runlistOffset ( int64_t offset ) {
  NonResident.runlistOffset = offset;
}

int64_t NTFSMFTEntry::get_runlistOffset () {
  return NonResident.runlistOffset;
}
