#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# (c) Camille Scott, 2019
# File   : traversal.py
# License: MIT
# Author : Camille Scott <camille.scott.w@gmail.com>
# Date   : 08.10.2019

from boink import libboink
from boink.utils import copy_attrs
from cppyy.gbl import std
from cppyy import gbl

dBGWalker = libboink.dBGWalker
STATES = libboink.TraversalState


class Assembler:
    
    def __init__(self, graph):
        self.graph = graph
        self.graphptr = self.graph.__smartptr__().get()
        self.walker = libboink.dBGWalker[type(graph)].dBG(graph.get_hasher())
        copy_attrs(libboink.dBGWalker[type(graph)],
                   self,
                   ['hash_type', 'shift_type', 'kmer_type'])
    
    def __getattr__(self, arg):
        attr = getattr(self.walker, arg)
        if callable(attr) and not attr.__name__.startswith('__'):
            def wrapper(*args, **kwargs):
                return attr(self.graphptr, *args, **kwargs)
            return wrapper
    
    def set_cursor(self, kmer):
        self.walker.set_cursor(kmer)

    @property
    def cursor(self):
        return self.walker.get_cursor()

    @cursor.setter
    def cursor(self, seed):
        self.walker.set_cursor(seed)
            
    def clear_seen(self):
        self.walker.clear_seen()
    
    def assemble_right(self, seed):
        mask = std.set[self.hash_type]()
        return self.walker.walk_right(self.graphptr, seed, mask)

    def assemble_left(self, seed):
        mask = std.set[self.hash_type]()
        return self.walker.walk_left(self.graphptr, seed, mask)
    
    def assemble(self, seed):
        mask = std.set[self.hash_type]()
        left_walk, right_walk = self.walker.walk(self.graphptr, seed, mask)
        return left_walk, right_walk
