#!/usr/bin/env python3

# Copyright (C) 2015 Canon Incorporated. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above
#    copyright notice, this list of conditions and the following
#    disclaimer.
# 2. Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials
#    provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

import sys
import argparse
import os

from webkitpy.common.checkout.scm.detection import SCMDetector
from webkitpy.common.host import Host
from webkitpy.common.system.filesystem import FileSystem

def usesFlatpak():
    return not os.environ.get('WEBKIT_JHBUILD') or os.environ.get('WEBKIT_JHBUILD') == '0'

def listWebKitBuildFiles(fs):
    ret = []
    if fs.isdir("WebKitBuild"):
        for build_dir in fs.listdir("WebKitBuild"):
            build_path = fs.join("WebKitBuild", build_dir)
            ret.append(build_path)
    return ret

def removeFiles(fs, l):
    for each in l:
        if fs.isdir(each):
            fs.rmtree(each)
        else:
            fs.remove(each)

def main(args):
    fs = FileSystem()
    host = Host()
    scm = SCMDetector(fs, host.executive).detect_scm_system(fs.getcwd())

    scm.discard_working_directory_changes()

    if args.keep_jhbuild_directory:
        # Clean everything inside WebKitBuild, except the JHBuild directories.
        scm.discard_untracked_files(discard_ignored_files=True, keep_webkitbuild_directory=True)
        if fs.isdir("WebKitBuild"):
            files = listWebKitBuildFiles(fs)
            keepDirs = usesFlatpak() and ["Toolchains", "UserFlatpak"] or ["DependenciesGTK", "DependenciesWPE"]
            files = [path for path in files if path[len("WebKitBuild/"):] not in keepDirs]
            removeFiles(fs, files)
    else:
        scm.discard_untracked_files(discard_ignored_files=True)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Clean WebKit")
    parser.add_argument("--keep-jhbuild-directory", action="store_true",
                        help="Don't wipe the JHBuild build directories.")

    args = parser.parse_args()
    sys.exit(main(args))
