# -*- coding: utf-8 -*-
#
# Copyright (C) 2016 Andi Albrecht, albrecht.andi@gmail.com
#
# This module is part of python-sqlparse and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php

from sqlparse import sql, tokens as T
from sqlparse.compat import text_type
from sqlparse.utils import split_unquoted_newlines


class StripCommentsFilter(object):
    @staticmethod
    def _process(tlist):
        def get_next_comment():
            # TODO(andi) Comment types should be unified, see related issue38
            return tlist.token_next_by(i=sql.Comment, t=T.Comment)

        token = get_next_comment()
        while token:
            prev = tlist.token_prev(token, skip_ws=False)
            next_ = tlist.token_next(token, skip_ws=False)
            # Replace by whitespace if prev and next exist and if they're not
            # whitespaces. This doesn't apply if prev or next is a paranthesis.
            if (prev is None or next_ is None or
                    prev.is_whitespace() or prev.match(T.Punctuation, '(') or
                    next_.is_whitespace() or next_.match(T.Punctuation, ')')):
                tlist.tokens.remove(token)
            else:
                tidx = tlist.token_index(token)
                tlist.tokens[tidx] = sql.Token(T.Whitespace, ' ')

            token = get_next_comment()

    def process(self, stmt):
        [self.process(sgroup) for sgroup in stmt.get_sublists()]
        StripCommentsFilter._process(stmt)
        return stmt


class StripWhitespaceFilter(object):
    def _stripws(self, tlist):
        func_name = '_stripws_%s' % tlist.__class__.__name__.lower()
        func = getattr(self, func_name, self._stripws_default)
        func(tlist)

    def _stripws_default(self, tlist):
        last_was_ws = False
        is_first_char = True
        for token in tlist.tokens:
            if token.is_whitespace():
                if last_was_ws or is_first_char:
                    token.value = ''
                else:
                    token.value = ' '
            last_was_ws = token.is_whitespace()
            is_first_char = False

    def _stripws_identifierlist(self, tlist):
        # Removes newlines before commas, see issue140
        last_nl = None
        for token in tlist.tokens[:]:
            if last_nl and token.ttype is T.Punctuation and token.value == ',':
                tlist.tokens.remove(last_nl)

            last_nl = token if token.is_whitespace() else None
        return self._stripws_default(tlist)

    def _stripws_parenthesis(self, tlist):
        if tlist.tokens[1].is_whitespace():
            tlist.tokens.pop(1)
        if tlist.tokens[-2].is_whitespace():
            tlist.tokens.pop(-2)
        self._stripws_default(tlist)

    def process(self, stmt, depth=0):
        [self.process(sgroup, depth + 1) for sgroup in stmt.get_sublists()]
        self._stripws(stmt)
        if depth == 0 and stmt.tokens and stmt.tokens[-1].is_whitespace():
            stmt.tokens.pop(-1)


class SpacesAroundOperatorsFilter(object):
    whitelist = (sql.Identifier, sql.Comparison, sql.Where)

    def _process(self, tlist):
        def next_token(idx):
            return tlist.token_next_by(t=(T.Operator, T.Comparison), idx=idx)

        idx = 0
        token = next_token(idx)
        while token:
            idx = tlist.token_index(token)
            if idx > 0 and tlist.tokens[idx - 1].ttype != T.Whitespace:
                # insert before
                tlist.tokens.insert(idx, sql.Token(T.Whitespace, ' '))
                idx += 1
            if idx < len(tlist.tokens) - 1:
                if tlist.tokens[idx + 1].ttype != T.Whitespace:
                    tlist.tokens.insert(idx + 1, sql.Token(T.Whitespace, ' '))

            idx += 1
            token = next_token(idx)

        for sgroup in tlist.get_sublists():
            self._process(sgroup)

    def process(self, stmt):
        self._process(stmt)


# ---------------------------
# postprocess

class SerializerUnicode(object):
    @staticmethod
    def process(stmt):
        raw = text_type(stmt)
        lines = split_unquoted_newlines(raw)
        return '\n'.join(line.rstrip() for line in lines)

@@ -3064,64 +3064,21 @@
     
-whitelist = (sql.Identifier, sql.Comparison, sql.Where)%0A
+@staticmethod
 %0A   
@@ -3091,22 +3091,16 @@
 process(
-self, 
 tlist):%0A
@@ -3125,16 +3125,18 @@
 oken(idx
+=0
 ):%0A     
@@ -3213,24 +3213,8 @@
 x)%0A%0A
-        idx = 0%0A
     
@@ -3236,19 +3236,16 @@
 t_token(
-idx
 )%0A      
@@ -3271,19 +3271,21 @@
         
-idx
+prev_
  = tlist
@@ -3287,35 +3287,49 @@
 tlist.token_
-index
+prev
 (token
+, skip_ws=False
 )%0A          
@@ -3337,41 +3337,23 @@
  if 
-idx %3E 0 and tlist.tokens%5Bidx - 1%5D
+prev_ and prev_
 .tty
@@ -3392,204 +3392,155 @@
     
-# 
+tlist.
 insert
- 
+_
 before
-%0A                tlist.tokens.insert(idx, sql.Token(T.Whitespace, ' '))%0A                idx += 1%0A            if idx %3C len(tlist.tokens) - 1:%0A                if tlist.tokens%5Bidx + 1%5D
+(token, sql.Token(T.Whitespace, ' '))%0A%0A            next_ = tlist.token_next(token, skip_ws=False)%0A            if next_ and next_
 .tty
@@ -3579,39 +3579,32 @@
     
-    
 tlist.
-tokens.insert(idx + 1
+insert_after(token
 , sq
@@ -3636,29 +3636,8 @@
 ))%0A%0A
-            idx += 1%0A
     
@@ -3666,26 +3666,83 @@
 oken(idx
+=token
 )%0A%0A    
-   
+def process(self, stmt):%0A        %5Bself.process(sgroup)
  for sgr
@@ -3748,20 +3748,19 @@
 roup in 
-tlis
+stm
 t.get_su
@@ -3767,17 +3767,17 @@
 blists()
-:
+%5D
 %0A       
@@ -3781,51 +3781,45 @@
     
-    self._process(sgroup)%0A%0A    def 
+SpacesAroundOperatorsFilter._
 process(
 self
@@ -3810,36 +3810,29 @@
 er._process(
-self, 
 stmt)
-:
 %0A        sel
@@ -3832,27 +3832,19 @@
     
-self._process(
+return 
 stmt
-)
 %0A%0A%0A#

Update SpacesAroundOperatorsFilter